widgetry/tools/
prompt_input.rs
1use crate::{
2 DrawBaselayer, EventCtx, GfxCtx, Key, Line, Outcome, Panel, State, TextBox, Transition, Widget,
3};
4
5pub struct PromptInput<A> {
7 panel: Panel,
8 cb: Option<Box<dyn FnOnce(String, &mut EventCtx, &mut A) -> Transition<A>>>,
9}
10
11impl<A: 'static> PromptInput<A> {
12 pub fn new_state(
13 ctx: &mut EventCtx,
14 query: &str,
15 initial: String,
16 cb: Box<dyn FnOnce(String, &mut EventCtx, &mut A) -> Transition<A>>,
17 ) -> Box<dyn State<A>> {
18 Box::new(PromptInput {
19 panel: Panel::new_builder(Widget::col(vec![
20 Widget::row(vec![
21 Line(query).small_heading().into_widget(ctx),
22 ctx.style().btn_close_widget(ctx),
23 ]),
24 TextBox::default_widget(ctx, "input", initial),
25 ctx.style()
26 .btn_outline
27 .text("confirm")
28 .hotkey(Key::Enter)
29 .build_def(ctx),
30 ]))
31 .build(ctx),
32 cb: Some(cb),
33 })
34 }
35}
36
37impl<A: 'static> State<A> for PromptInput<A> {
38 fn event(&mut self, ctx: &mut EventCtx, app: &mut A) -> Transition<A> {
39 match self.panel.event(ctx) {
40 Outcome::Clicked(x) => match x.as_ref() {
41 "close" => Transition::Pop,
42 "confirm" => {
43 let data = self.panel.text_box("input");
44 (self.cb.take().unwrap())(data, ctx, app)
45 }
46 _ => unreachable!(),
47 },
48 _ => {
49 if ctx.normal_left_click() && ctx.canvas.get_cursor_in_screen_space().is_none() {
50 return Transition::Pop;
51 }
52 Transition::Keep
53 }
54 }
55 }
56
57 fn draw_baselayer(&self) -> DrawBaselayer {
58 DrawBaselayer::PreviousState
59 }
60
61 fn draw(&self, g: &mut GfxCtx, _: &A) {
62 super::grey_out_map(g);
63 self.panel.draw(g);
64 }
65}