feat: show help in modal dialog

This commit is contained in:
Jeremy Wall 2024-11-22 15:58:28 -05:00
parent 86f008a2a8
commit 185bac14fc

View File

@ -92,8 +92,7 @@ pub struct Workspace<'ws> {
state: AppState<'ws>, state: AppState<'ws>,
text_area: TextArea<'ws>, text_area: TextArea<'ws>,
dirty: bool, dirty: bool,
show_help: bool, popup: Vec<String>
popup: String
} }
impl<'ws> Workspace<'ws> { impl<'ws> Workspace<'ws> {
@ -104,8 +103,7 @@ impl<'ws> Workspace<'ws> {
state: AppState::default(), state: AppState::default(),
text_area: reset_text_area("".to_owned()), text_area: reset_text_area("".to_owned()),
dirty: false, dirty: false,
show_help: false, popup: Vec::new(),
popup: String::new(),
}; };
ws.handle_movement_change(); ws.handle_movement_change();
ws ws
@ -176,33 +174,30 @@ impl<'ws> Workspace<'ws> {
Ok(None) Ok(None)
} }
fn render_help_text(&self) -> impl Widget { fn render_help_text(&self) -> Vec<String> {
let info_block = Block::bordered().title("Help"); match self.state.modality() {
Paragraph::new(match self.state.modality() { Modality::Navigate => vec![
Modality::Navigate => Text::from(vec![ "Navigate Mode:".to_string(),
"Navigate Mode:".into(), "* e: Enter edit mode for current cell".to_string(),
"* e: Enter edit mode for current cell".into(), "* h,j,k,l: vim style navigation".to_string(),
"* h,j,k,l: vim style navigation".into(), "* CTRl-r: Add a row".to_string(),
"* CTRl-r: Add a row".into(), "* CTRl-c: Add a column".to_string(),
"* CTRl-c: Add a column".into(), "* q exit".to_string(),
"* q exit".into(), "* Ctrl-S Save sheet".to_string(),
"* Ctrl-S Save sheet".into(), ],
]), Modality::CellEdit => vec![
Modality::CellEdit => Text::from(vec![ "Edit Mode:".to_string(),
"Edit Mode:".into(), "* ESC: Exit edit mode".to_string(),
"* ESC: Exit edit mode".into(), "Otherwise edit as normal".to_string(),
"Otherwise edit as normal".into(), ],
]), Modality::Command => vec![
Modality::Command => Text::from(vec![ "Command Mode:".to_string(),
"Command Mode:".into(), "* ESC: Exit command mode".to_string(),
"* ESC: Exit command mode".into(), ],
]), _ => vec![
Modality::Dialog => Text::from(vec![ "General help".to_string(),
"Dialog Mode:".into(), ],
"* ESC: Exit dialog".into(), }
]),
})
.block(info_block)
} }
fn handle_command_input(&mut self, key: event::KeyEvent) -> Result<Option<ExitCode>> { fn handle_command_input(&mut self, key: event::KeyEvent) -> Result<Option<ExitCode>> {
@ -234,7 +229,7 @@ impl<'ws> Workspace<'ws> {
if key.kind == KeyEventKind::Press { if key.kind == KeyEventKind::Press {
match key.code { match key.code {
KeyCode::Char('h') if key.modifiers == KeyModifiers::CONTROL => { KeyCode::Char('h') if key.modifiers == KeyModifiers::CONTROL => {
self.show_help = !self.show_help; self.enter_dialog_mode(self.render_help_text());
} }
KeyCode::Esc | KeyCode::Enter => self.exit_edit_mode()?, KeyCode::Esc | KeyCode::Enter => self.exit_edit_mode()?,
_ => { _ => {
@ -262,7 +257,7 @@ impl<'ws> Workspace<'ws> {
Ok(true) Ok(true)
} }
Ok(Some(Cmd::Help(_maybe_topic))) => { Ok(Some(Cmd::Help(_maybe_topic))) => {
self.enter_dialog_mode("TODO help topic".to_owned()); self.enter_dialog_mode(vec!["TODO help topic".to_owned()]);
Ok(true) Ok(true)
} }
Ok(Some(Cmd::Write(maybe_path))) => { Ok(Some(Cmd::Write(maybe_path))) => {
@ -288,11 +283,11 @@ impl<'ws> Workspace<'ws> {
std::process::exit(0); std::process::exit(0);
}, },
Ok(None) => { Ok(None) => {
self.enter_dialog_mode(format!("Unrecognized commmand {}", cmd_text)); self.enter_dialog_mode(vec![format!("Unrecognized commmand {}", cmd_text)]);
Ok(false) Ok(false)
}, },
Err(msg) => { Err(msg) => {
self.enter_dialog_mode(msg.to_owned()); self.enter_dialog_mode(vec![msg.to_owned()]);
Ok(false) Ok(false)
} }
} }
@ -308,7 +303,7 @@ impl<'ws> Workspace<'ws> {
self.enter_command_mode(); self.enter_command_mode();
} }
KeyCode::Char('h') if key.modifiers == KeyModifiers::CONTROL => { KeyCode::Char('h') if key.modifiers == KeyModifiers::CONTROL => {
self.show_help = !self.show_help; self.enter_dialog_mode(self.render_help_text());
} }
KeyCode::Char('s') if key.modifiers == KeyModifiers::CONTROL => { KeyCode::Char('s') if key.modifiers == KeyModifiers::CONTROL => {
self.save_file()?; self.save_file()?;
@ -383,7 +378,7 @@ impl<'ws> Workspace<'ws> {
self.state.command_state.focus(); self.state.command_state.focus();
} }
fn enter_dialog_mode(&mut self, msg: String) { fn enter_dialog_mode(&mut self, msg: Vec<String>) {
self.popup = msg; self.popup = msg;
self.state.modality_stack.push(Modality::Dialog); self.state.modality_stack.push(Modality::Dialog);
} }
@ -466,13 +461,6 @@ impl<'ws> Workspace<'ws> {
}), }),
]; ];
if self.show_help {
cs.push(Constraint::Fill(9));
rs.push(Box::new(|rect: Rect, buf: &mut Buffer, ws: &mut Self| {
let info_para = ws.render_help_text();
info_para.render(rect, buf);
}));
}
if self.state.modality() == &Modality::Command { if self.state.modality() == &Modality::Command {
cs.push(Constraint::Max(1)); cs.push(Constraint::Max(1));
rs.push(Box::new(|rect: Rect, buf: &mut Buffer, ws: &mut Self| { rs.push(Box::new(|rect: Rect, buf: &mut Buffer, ws: &mut Self| {
@ -550,7 +538,8 @@ impl<'widget, 'ws: 'widget> Widget for &'widget mut Workspace<'ws> {
outer_block.render(area, buf); outer_block.render(area, buf);
if self.state.modality() == &Modality::Dialog { if self.state.modality() == &Modality::Dialog {
let popup = Popup::new(Text::from(self.popup.clone())); let lines = Text::from_iter(self.popup.iter().cloned());
let popup = Popup::new(lines);
popup.render(area, buf); popup.render(area, buf);
} }
} }