generated from GarandPLG/rust-flake-template
Add text input handling to settings popup
Introduce a `selected_setting_new_value` field in `SettingsState` and initialize it. Add `Backspace` and `WildCard(char)` actions with an `Input` group, and corresponding keybindings. Update `event_to_action` to map wildcard characters to `Action::WildCard`. Handle backspace and character input in `settings_keybindings` to edit the new field. Display the edited value in the settings popup and include the new actions in the UI.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct GameStates {
|
pub struct GameStates {
|
||||||
pub main_menu_state: MainMenuState,
|
pub main_menu_state: MainMenuState,
|
||||||
pub skirmish_state: SkirmishState,
|
pub skirmish_state: SkirmishState,
|
||||||
@@ -34,12 +34,13 @@ pub struct SkillsConfigState {
|
|||||||
pub selected_skill: usize,
|
pub selected_skill: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct SettingsState {
|
pub struct SettingsState {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub selected_setting: usize,
|
pub selected_setting: usize,
|
||||||
pub show_popup: bool,
|
pub show_popup: bool,
|
||||||
|
pub selected_setting_new_value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameStates {
|
impl GameStates {
|
||||||
@@ -69,6 +70,7 @@ impl GameStates {
|
|||||||
name: "Settings",
|
name: "Settings",
|
||||||
selected_setting: 0,
|
selected_setting: 0,
|
||||||
show_popup: false,
|
show_popup: false,
|
||||||
|
selected_setting_new_value: String::new(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,15 @@ pub enum Action {
|
|||||||
Space,
|
Space,
|
||||||
Enter,
|
Enter,
|
||||||
Esc,
|
Esc,
|
||||||
|
Backspace,
|
||||||
|
WildCard(char),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
|
||||||
pub enum Group {
|
pub enum Group {
|
||||||
Movement,
|
Movement,
|
||||||
Select,
|
Select,
|
||||||
|
Input,
|
||||||
Quit,
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +97,24 @@ pub static KEYBINDINGS: &[KeyBinding] = &[
|
|||||||
symbol: "Esc",
|
symbol: "Esc",
|
||||||
description: "Go back",
|
description: "Go back",
|
||||||
},
|
},
|
||||||
|
KeyBinding {
|
||||||
|
action: Action::Backspace,
|
||||||
|
code: KeyCode::Backspace,
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
group: Group::Input,
|
||||||
|
symbol: "Backspace",
|
||||||
|
description: "Delete character",
|
||||||
|
},
|
||||||
|
KeyBinding {
|
||||||
|
action: Action::WildCard('_'),
|
||||||
|
code: KeyCode::Char('_'),
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
group: Group::Input,
|
||||||
|
symbol: "*",
|
||||||
|
description: "All keyboard characters",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn binding_for(action: Action) -> Option<&'static KeyBinding> {
|
pub fn binding_for(action: Action) -> Option<&'static KeyBinding> {
|
||||||
@@ -101,8 +122,22 @@ pub fn binding_for(action: Action) -> Option<&'static KeyBinding> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn event_to_action(event: &KeyEvent) -> Option<Action> {
|
pub fn event_to_action(event: &KeyEvent) -> Option<Action> {
|
||||||
KEYBINDINGS
|
if let Some(b) = KEYBINDINGS
|
||||||
.iter()
|
.iter()
|
||||||
.find(|b| b.code == event.code && b.kind == event.kind && b.modifiers == event.modifiers)
|
.find(|b| b.code == event.code && b.kind == event.kind && b.modifiers == event.modifiers)
|
||||||
.map(|b| b.action)
|
{
|
||||||
|
return Some(b.action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if KEYBINDINGS.iter().any(|b| {
|
||||||
|
matches!(b.action, Action::WildCard(_))
|
||||||
|
&& b.kind == event.kind
|
||||||
|
&& b.modifiers == event.modifiers
|
||||||
|
}) {
|
||||||
|
if let KeyCode::Char(c) = event.code {
|
||||||
|
return Some(Action::WildCard(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use ratatui::crossterm::event::KeyEvent;
|
|||||||
pub fn settings_keybindings(app: &mut App, key_event: &KeyEvent) {
|
pub fn settings_keybindings(app: &mut App, key_event: &KeyEvent) {
|
||||||
if let Some(action) = event_to_action(&key_event) {
|
if let Some(action) = event_to_action(&key_event) {
|
||||||
match action {
|
match action {
|
||||||
|
// Action::Up,
|
||||||
|
// Action::Down,
|
||||||
Action::Quit => app.exit = true,
|
Action::Quit => app.exit = true,
|
||||||
Action::Quit2 => app.exit = true,
|
Action::Quit2 => app.exit = true,
|
||||||
Action::Esc => app.view = View::MainMenu,
|
Action::Esc => app.view = View::MainMenu,
|
||||||
@@ -14,6 +16,22 @@ pub fn settings_keybindings(app: &mut App, key_event: &KeyEvent) {
|
|||||||
app.game_states.settings_state.show_popup =
|
app.game_states.settings_state.show_popup =
|
||||||
!app.game_states.settings_state.show_popup
|
!app.game_states.settings_state.show_popup
|
||||||
}
|
}
|
||||||
|
Action::Backspace => {
|
||||||
|
if app.game_states.settings_state.show_popup {
|
||||||
|
app.game_states
|
||||||
|
.settings_state
|
||||||
|
.selected_setting_new_value
|
||||||
|
.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Action::WildCard(c) => {
|
||||||
|
if app.game_states.settings_state.show_popup {
|
||||||
|
app.game_states
|
||||||
|
.settings_state
|
||||||
|
.selected_setting_new_value
|
||||||
|
.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ pub fn default_view(area: Rect, buf: &mut Buffer) {
|
|||||||
|
|
||||||
let [main_area, keybindings_area] = vertical_layout.areas(area);
|
let [main_area, keybindings_area] = vertical_layout.areas(area);
|
||||||
|
|
||||||
|
{
|
||||||
Paragraph::new("Work in progress")
|
Paragraph::new("Work in progress")
|
||||||
.alignment(Alignment::Center)
|
.alignment(Alignment::Center)
|
||||||
.yellow()
|
.yellow()
|
||||||
@@ -20,6 +21,7 @@ pub fn default_view(area: Rect, buf: &mut Buffer) {
|
|||||||
.borders(Borders::LEFT | Borders::TOP | Borders::RIGHT),
|
.borders(Borders::LEFT | Borders::TOP | Borders::RIGHT),
|
||||||
)
|
)
|
||||||
.render(main_area, buf);
|
.render(main_area, buf);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let actions: Vec<Action> = vec![Action::Quit, Action::Quit2, Action::Esc];
|
let actions: Vec<Action> = vec![Action::Quit, Action::Quit2, Action::Esc];
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub fn settings_view(app: &App, area: Rect, buf: &mut Buffer) {
|
|||||||
|
|
||||||
let [title_area, main_area, keybindings_area] = vertical_layout.areas(area);
|
let [title_area, main_area, keybindings_area] = vertical_layout.areas(area);
|
||||||
|
|
||||||
|
{
|
||||||
Paragraph::new("War in tunnels")
|
Paragraph::new("War in tunnels")
|
||||||
.alignment(Alignment::Left)
|
.alignment(Alignment::Left)
|
||||||
.yellow()
|
.yellow()
|
||||||
@@ -37,14 +38,19 @@ pub fn settings_view(app: &App, area: Rect, buf: &mut Buffer) {
|
|||||||
)
|
)
|
||||||
.render(main_area, buf);
|
.render(main_area, buf);
|
||||||
|
|
||||||
let popup_area = Rect {
|
let popup_area: Rect = Rect {
|
||||||
x: main_area.width / 4,
|
x: main_area.width / 4,
|
||||||
y: main_area.height / 3,
|
y: main_area.height / 3,
|
||||||
width: main_area.width / 2,
|
width: main_area.width / 2,
|
||||||
height: main_area.height / 3,
|
height: main_area.height / 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
let popup = Paragraph::new("Test popup")
|
let popup: Paragraph<'_> = Paragraph::new(
|
||||||
|
app.game_states
|
||||||
|
.settings_state
|
||||||
|
.selected_setting_new_value
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
.wrap(Wrap { trim: true })
|
.wrap(Wrap { trim: true })
|
||||||
.style(Style::default().yellow())
|
.style(Style::default().yellow())
|
||||||
.block(
|
.block(
|
||||||
@@ -58,16 +64,19 @@ pub fn settings_view(app: &App, area: Rect, buf: &mut Buffer) {
|
|||||||
if app.game_states.settings_state.show_popup {
|
if app.game_states.settings_state.show_popup {
|
||||||
popup.render(popup_area, buf);
|
popup.render(popup_area, buf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let actions: Vec<Action> = vec![
|
let actions: Vec<Action> = vec![
|
||||||
Action::Up,
|
Action::Up,
|
||||||
Action::Down,
|
Action::Down,
|
||||||
Action::Space,
|
|
||||||
Action::Enter,
|
|
||||||
Action::Quit,
|
Action::Quit,
|
||||||
Action::Quit2,
|
Action::Quit2,
|
||||||
Action::Esc,
|
Action::Esc,
|
||||||
|
Action::Space,
|
||||||
|
Action::Enter,
|
||||||
|
Action::Backspace,
|
||||||
|
Action::WildCard('_'),
|
||||||
];
|
];
|
||||||
|
|
||||||
KeybindingsWidget::new(actions).render(keybindings_area, buf);
|
KeybindingsWidget::new(actions).render(keybindings_area, buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user