display text entry boxes in the middle of the screen, not as part of the bottom OSD

This commit is contained in:
Dustin Carlino 2018-09-20 18:22:20 -07:00
parent d9eef240aa
commit 1d7417e851
7 changed files with 53 additions and 40 deletions

View File

@ -188,3 +188,11 @@ One UI plugin at a time:
- https://docs.rs/euclid/0.19.0/euclid/struct.TypedTransform2D.html
- https://www.reddit.com/r/rust/comments/6sukcw/is_it_possible_to_to_create_an_ortho_view_in_glium/ has a direct example of affine transformation
- https://www.reddit.com/r/gamedev/comments/4mn9ly/3d_matrix_transformation_question_rotating/
## Wizard
API looks like coroutines/continuations, but it just works by replaying
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.

View File

@ -65,7 +65,7 @@ impl DrawPolygonState {
&& input.key_pressed(Key::Return, "confirm the polygon's shape")
{
new_state = Some(DrawPolygonState::NamingPolygon(
TextBox::new_prefilled(name.clone()),
TextBox::new_prefilled("Name this polygon", name.clone()),
pts.clone(),
));
}
@ -115,9 +115,6 @@ impl DrawPolygonState {
).expect("Saving polygon selection failed");
println!("Saved {}", path);
new_state = Some(DrawPolygonState::Empty);
} else {
osd.pad_if_nonempty();
tb.populate_osd(osd);
}
input.consume_event();
}
@ -159,8 +156,9 @@ impl DrawPolygonState {
}
DrawPolygonState::DrawingPoints(pts, current_idx, _) => (pts, *current_idx),
DrawPolygonState::MovingPoint(pts, idx, _) => (pts, Some(*idx)),
DrawPolygonState::NamingPolygon(_, pts) => {
DrawPolygonState::NamingPolygon(tb, pts) => {
g.draw_polygon(blue, &Polygon::new(pts));
tb.draw(g, canvas);
return;
}
DrawPolygonState::ListingPolygons(menu, polygons) => {

View File

@ -1,7 +1,7 @@
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
use colors::{ColorScheme, Colors};
use ezgui::{TextBox, TextOSD, UserInput};
use ezgui::{Canvas, GfxCtx, TextBox, UserInput};
use graphics::types::Color;
use objects::{Ctx, ID};
use piston::input::Key;
@ -26,20 +26,19 @@ impl SearchState {
None
}
pub fn event(&mut self, input: &mut UserInput, osd: &mut TextOSD) -> bool {
pub fn event(&mut self, input: &mut UserInput) -> bool {
let mut new_state: Option<SearchState> = None;
match self {
SearchState::Empty => {
if input.unimportant_key_pressed(Key::Slash, "start searching") {
new_state = Some(SearchState::EnteringSearch(TextBox::new()));
new_state = Some(SearchState::EnteringSearch(TextBox::new(
"Search for what?",
)));
}
}
SearchState::EnteringSearch(tb) => {
if tb.event(input.use_event_directly()) {
new_state = Some(SearchState::FilterOSM(tb.line.clone()));
} else {
osd.pad_if_nonempty();
tb.populate_osd(osd);
}
input.consume_event();
}
@ -60,6 +59,12 @@ impl SearchState {
_ => true,
}
}
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
if let SearchState::EnteringSearch(tb) = self {
tb.draw(g, canvas);
}
}
}
impl Colorizer for SearchState {

View File

@ -1,4 +1,4 @@
use ezgui::{Canvas, TextBox, TextOSD, UserInput};
use ezgui::{Canvas, GfxCtx, TextBox, UserInput};
use geom::Pt2D;
use map_model::{AreaID, BuildingID, IntersectionID, LaneID, Map, ParcelID, RoadID};
use objects::ID;
@ -20,23 +20,19 @@ impl WarpState {
sim: &Sim,
canvas: &mut Canvas,
selected: &mut Option<ID>,
osd: &mut TextOSD,
) -> bool {
let mut new_state: Option<WarpState> = None;
match self {
WarpState::Empty => {
if input.unimportant_key_pressed(Key::J, "start searching for something to warp to")
{
new_state = Some(WarpState::EnteringSearch(TextBox::new()));
new_state = Some(WarpState::EnteringSearch(TextBox::new("Warp to what?")));
}
}
WarpState::EnteringSearch(tb) => {
if tb.event(input.use_event_directly()) {
warp(tb.line.clone(), map, sim, canvas, selected);
new_state = Some(WarpState::Empty);
} else {
osd.pad_if_nonempty();
tb.populate_osd(osd);
}
input.consume_event();
}
@ -49,6 +45,12 @@ impl WarpState {
_ => true,
}
}
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
if let WarpState::EnteringSearch(tb) = self {
tb.draw(g, canvas);
}
}
}
impl Colorizer for WarpState {}

View File

@ -70,6 +70,9 @@ impl WizardSample {
);
}
}
if let Some(ref tb) = wizard.tb {
tb.draw(g, canvas);
}
}
}
}
@ -193,7 +196,6 @@ impl Wizard {
&mut self,
query: &str,
input: &mut UserInput,
osd: &mut TextOSD,
parser: Box<Fn(String) -> Option<R>>,
) -> Option<R> {
assert!(self.alive);
@ -204,7 +206,7 @@ impl Wizard {
}
if self.tb.is_none() {
self.tb = Some(TextBox::new());
self.tb = Some(TextBox::new(query));
}
let done = self.tb.as_mut().unwrap().event(input.use_event_directly());
@ -220,9 +222,6 @@ impl Wizard {
None
}
} else {
osd.pad_if_nonempty();
osd.add_line(query.to_string());
self.tb.as_ref().unwrap().populate_osd(osd);
None
}
}
@ -250,7 +249,6 @@ impl<'a> WrappedWizard<'a> {
if let Some(num) = self.wizard.input_with_text_box(
query,
self.input,
self.osd,
Box::new(|line| line.parse::<usize>().ok()),
) {
self.wizard.state_usize.push(num);
@ -264,12 +262,10 @@ impl<'a> WrappedWizard<'a> {
if !self.ready_tick.is_empty() {
return self.ready_tick.pop_front();
}
if let Some(tick) = self.wizard.input_with_text_box(
query,
self.input,
self.osd,
Box::new(|line| Tick::parse(&line)),
) {
if let Some(tick) =
self.wizard
.input_with_text_box(query, self.input, Box::new(|line| Tick::parse(&line)))
{
self.wizard.state_tick.push(tick);
Some(tick)
} else {
@ -284,7 +280,6 @@ impl<'a> WrappedWizard<'a> {
if let Some(percent) = self.wizard.input_with_text_box(
query,
self.input,
self.osd,
Box::new(|line| {
line.parse::<f64>().ok().and_then(|num| {
if num >= 0.0 && num <= 1.0 {

View File

@ -199,15 +199,14 @@ impl UIWrapper {
&mut ui.sim,
)
}),
Box::new(|ui, input, osd| ui.search_state.event(input, osd)),
Box::new(|ui, input, osd| {
Box::new(|ui, input, _osd| ui.search_state.event(input)),
Box::new(|ui, input, _osd| {
ui.warp.event(
input,
&ui.map,
&ui.sim,
&mut ui.canvas,
&mut ui.current_selection,
osd,
)
}),
Box::new(|ui, input, _osd| {
@ -463,6 +462,8 @@ impl UI {
self.color_picker.draw(&self.canvas, g);
self.draw_polygon.draw(g, &self.canvas);
self.wizard_sample.draw(g, &self.canvas);
self.search_state.draw(g, &self.canvas);
self.warp.draw(g, &self.canvas);
self.canvas.draw_osd_notification(g, osd);
}

View File

@ -1,33 +1,37 @@
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
use keys::key_to_char;
use piston::input::{Button, ButtonEvent, Event, Key, PressEvent, ReleaseEvent};
use TextOSD;
use {Canvas, GfxCtx, TextOSD};
// TODO right now, only a single line
pub struct TextBox {
prompt: String,
// TODO A rope would be cool.
// TODO dont be pub
pub line: String,
cursor_x: usize,
shift_pressed: bool,
}
impl TextBox {
pub fn new() -> TextBox {
TextBox::new_prefilled(String::from(""))
pub fn new(prompt: &str) -> TextBox {
TextBox::new_prefilled(prompt, String::from(""))
}
pub fn new_prefilled(line: String) -> TextBox {
pub fn new_prefilled(prompt: &str, line: String) -> TextBox {
TextBox {
prompt: prompt.to_string(),
line,
cursor_x: 0,
shift_pressed: false,
}
}
pub fn populate_osd(&self, osd: &mut TextOSD) {
pub fn draw(&self, g: &mut GfxCtx, canvas: &Canvas) {
let mut osd = TextOSD::new();
osd.add_highlighted_line(self.prompt.clone());
osd.add_line_with_cursor(self.line.clone(), self.cursor_x);
canvas.draw_centered_text(g, osd);
}
// TODO a way to abort out