Add new confirm dialog
This commit is contained in:
parent
7e6d18c252
commit
3e3169dd27
@ -22,7 +22,8 @@ async fn run_app<B: Backend>(terminal: &mut Terminal<B>) -> Result<(), Box<dyn E
|
|||||||
/*let mut rules = GameRules::default();
|
/*let mut rules = GameRules::default();
|
||||||
rules.boats_can_touch = true;
|
rules.boats_can_touch = true;
|
||||||
let res = set_boats_layout::set_boat_layout(&rules, terminal)?; // select_bot_type::select_bot_type(terminal)?;*/
|
let res = set_boats_layout::set_boat_layout(&rules, terminal)?; // select_bot_type::select_bot_type(terminal)?;*/
|
||||||
let res = popup_screen::popup_screen("Hi\nWelcome there", terminal);
|
/*let res = popup_screen::popup_screen("Hi\nWelcome there", terminal);*/
|
||||||
|
let res = confirm_dialog::confirm_dialog("Do you really want to interrupt game ?", terminal)?; // select_bot_type::select_bot_type(terminal)?;
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(
|
||||||
ErrorKind::Other,
|
ErrorKind::Other,
|
||||||
format!("result: {:?}", res),
|
format!("result: {:?}", res),
|
||||||
|
112
rust/cli_player/src/ui_screens/confirm_dialog.rs
Normal file
112
rust/cli_player/src/ui_screens/confirm_dialog.rs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
use std::io;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
use crossterm::event;
|
||||||
|
use crossterm::event::{Event, KeyCode};
|
||||||
|
use tui::backend::Backend;
|
||||||
|
use tui::layout::*;
|
||||||
|
use tui::text::*;
|
||||||
|
use tui::widgets::*;
|
||||||
|
use tui::{Frame, Terminal};
|
||||||
|
|
||||||
|
use crate::constants::*;
|
||||||
|
use crate::ui_screens::utils::centered_rect_size;
|
||||||
|
use crate::ui_screens::ScreenResult;
|
||||||
|
use crate::ui_widgets::button_widget::ButtonWidget;
|
||||||
|
|
||||||
|
struct ConfirmDialogScreen<'a> {
|
||||||
|
title: &'a str,
|
||||||
|
msg: &'a str,
|
||||||
|
is_confirm: bool,
|
||||||
|
can_cancel: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn confirm_dialog<B: Backend>(
|
||||||
|
msg: &str,
|
||||||
|
terminal: &mut Terminal<B>,
|
||||||
|
) -> io::Result<ScreenResult<bool>> {
|
||||||
|
let mut model = ConfirmDialogScreen {
|
||||||
|
title: "Confirmation Request",
|
||||||
|
msg,
|
||||||
|
is_confirm: true,
|
||||||
|
can_cancel: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut last_tick = Instant::now();
|
||||||
|
loop {
|
||||||
|
terminal.draw(|f| ui(f, &mut model))?;
|
||||||
|
|
||||||
|
let timeout = TICK_RATE
|
||||||
|
.checked_sub(last_tick.elapsed())
|
||||||
|
.unwrap_or_else(|| Duration::from_secs(0));
|
||||||
|
|
||||||
|
if event::poll(timeout)? {
|
||||||
|
if let Event::Key(key) = event::read()? {
|
||||||
|
match key.code {
|
||||||
|
KeyCode::Esc | KeyCode::Char('q') if model.can_cancel => {
|
||||||
|
return Ok(ScreenResult::Canceled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle selected choice
|
||||||
|
KeyCode::Left | KeyCode::Right | KeyCode::Tab => {
|
||||||
|
model.is_confirm = !model.is_confirm
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit choice
|
||||||
|
KeyCode::Enter => {
|
||||||
|
return Ok(ScreenResult::Ok(model.is_confirm));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if last_tick.elapsed() >= TICK_RATE {
|
||||||
|
last_tick = Instant::now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ui<B: Backend>(f: &mut Frame<B>, model: &mut ConfirmDialogScreen) {
|
||||||
|
// Preprocess message
|
||||||
|
let lines = textwrap::wrap(model.msg, f.size().width as usize - 20);
|
||||||
|
let line_max_len = lines.iter().map(|l| l.len()).max().unwrap();
|
||||||
|
|
||||||
|
let area = centered_rect_size(line_max_len as u16 + 4, 5 + lines.len() as u16, &f.size());
|
||||||
|
|
||||||
|
let block = Block::default().borders(Borders::ALL).title(model.title);
|
||||||
|
f.render_widget(block, area);
|
||||||
|
|
||||||
|
// Create two chunks with equal horizontal screen space
|
||||||
|
let chunks = Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.constraints(
|
||||||
|
[
|
||||||
|
Constraint::Length(lines.len() as u16),
|
||||||
|
Constraint::Length(3),
|
||||||
|
]
|
||||||
|
.as_ref(),
|
||||||
|
)
|
||||||
|
.split(area.inner(&Margin {
|
||||||
|
horizontal: 2,
|
||||||
|
vertical: 1,
|
||||||
|
}));
|
||||||
|
|
||||||
|
let text = lines
|
||||||
|
.iter()
|
||||||
|
.map(|s| Spans::from(s.as_ref()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let paragraph = Paragraph::new(text);
|
||||||
|
f.render_widget(paragraph, chunks[0]);
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
let buttons_area = Layout::default()
|
||||||
|
.direction(Direction::Horizontal)
|
||||||
|
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||||
|
.split(chunks[1]);
|
||||||
|
|
||||||
|
let cancel_button = ButtonWidget::new("Cancel", true).set_disabled(model.is_confirm);
|
||||||
|
f.render_widget(cancel_button, buttons_area[0]);
|
||||||
|
|
||||||
|
let ok_button = ButtonWidget::new("Confirm", true).set_disabled(!model.is_confirm);
|
||||||
|
f.render_widget(ok_button, buttons_area[1]);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
pub mod configure_game_rules;
|
pub mod configure_game_rules;
|
||||||
|
pub mod confirm_dialog;
|
||||||
pub mod popup_screen;
|
pub mod popup_screen;
|
||||||
pub mod select_bot_type;
|
pub mod select_bot_type;
|
||||||
pub mod select_play_mode;
|
pub mod select_play_mode;
|
||||||
|
Loading…
Reference in New Issue
Block a user