Implement section selection for edit mode

This commit is contained in:
Patrick Auernig 2023-08-15 15:06:32 +02:00
parent ccf7376637
commit 7eaabc0f63
6 changed files with 124 additions and 17 deletions

View File

@ -30,3 +30,4 @@ wayfarer --path <path-to-savefile>
| q | Normal | Quits the application | | q | Normal | Quits the application |
| o | Normal | Open a new file | | o | Normal | Open a new file |
| w | Normal | Toggle file watcher mode (requires "watch" feature) | | w | Normal | Toggle file watcher mode (requires "watch" feature) |
| H,J,K,L | Edit | Move between sections |

View File

@ -19,7 +19,7 @@ use crossterm::terminal::{
use ratatui::backend::CrosstermBackend; use ratatui::backend::CrosstermBackend;
use tracing::{debug, error, info}; use tracing::{debug, error, info};
use self::state::{Mode, State}; use self::state::{Mode, Section, State};
type Terminal = ratatui::Terminal<CrosstermBackend<Stdout>>; type Terminal = ratatui::Terminal<CrosstermBackend<Stdout>>;
@ -46,6 +46,14 @@ pub enum Message {
ToggleFileWatch, ToggleFileWatch,
ReloadFile, ReloadFile,
MoveSectionLeft,
MoveSectionDown,
MoveSectionUp,
MoveSectionRight,
} }
@ -151,6 +159,38 @@ fn handle_message(
state.reload_active_savefile()?; state.reload_active_savefile()?;
} }
Message::MoveSectionLeft => {
state.active_section = match state.active_section {
Section::Companions => Section::General,
_ => Section::Companions,
};
}
Message::MoveSectionRight => {
state.active_section = match state.active_section {
Section::Companions => Section::General,
_ => Section::Companions,
}
}
Message::MoveSectionDown => {
state.active_section = match state.active_section {
Section::General => Section::Glyphs,
Section::Glyphs => Section::Murals,
Section::Murals => Section::General,
section => section,
};
}
Message::MoveSectionUp => {
state.active_section = match state.active_section {
Section::General => Section::Murals,
Section::Glyphs => Section::General,
Section::Murals => Section::Glyphs,
section => section,
}
}
_ => (), _ => (),
} }

View File

@ -77,6 +77,26 @@ fn handle_keyboard_input(
msg_tx.send(Message::ReloadFile)?; msg_tx.send(Message::ReloadFile)?;
} }
(Mode::Edit, KeyCode::Char('H')) => {
msg_tx.send(Message::MoveSectionLeft)?;
}
(Mode::Edit, KeyCode::Char('J')) => {
msg_tx.send(Message::MoveSectionDown)?;
}
(Mode::Edit, KeyCode::Char('K')) => {
msg_tx.send(Message::MoveSectionUp)?;
}
(Mode::Edit, KeyCode::Char('L')) => {
msg_tx.send(Message::MoveSectionRight)?;
}
(Mode::Normal, KeyCode::Char('e')) => {
msg_tx.send(Message::SetMode(Mode::Edit))?;
}
#[cfg(feature = "watch")] #[cfg(feature = "watch")]
(Mode::Normal, KeyCode::Char('w')) => { (Mode::Normal, KeyCode::Char('w')) => {
msg_tx.send(Message::ToggleFileWatch)?; msg_tx.send(Message::ToggleFileWatch)?;

View File

@ -18,15 +18,28 @@ pub enum Mode {
#[default] #[default]
Normal, Normal,
Edit,
ShowError(String), ShowError(String),
SelectFile, SelectFile,
} }
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum Section {
#[default]
General,
Glyphs,
Murals,
Companions,
}
#[derive(Default)] #[derive(Default)]
pub struct State { pub struct State {
savefile: Option<Savefile>, savefile: Option<Savefile>,
pub active_section: Section,
pub mode: Mode, pub mode: Mode,
pub file_select: Input, pub file_select: Input,
#[cfg(feature = "watch")] #[cfg(feature = "watch")]
@ -46,10 +59,7 @@ impl State {
Ok(Self { Ok(Self {
savefile, savefile,
mode: Mode::default(), ..Default::default()
file_select: Input::default(),
#[cfg(feature = "watch")]
file_watcher: None,
}) })
} }

View File

@ -1,14 +1,16 @@
use jrny_save::{Savefile, LEVEL_NAMES}; use jrny_save::{Savefile, LEVEL_NAMES};
use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect}; use ratatui::layout::{Alignment, Constraint, Direction, Layout, Rect};
use ratatui::style::Style;
use ratatui::widgets::{Block, Borders, Cell, Padding, Paragraph, Row, Table}; use ratatui::widgets::{Block, Borders, Cell, Padding, Paragraph, Row, Table};
use crate::tui::state::{Mode, Section};
use crate::tui::view::Frame; use crate::tui::view::Frame;
use crate::tui::State; use crate::tui::State;
pub fn render(state: &mut State, frame: &mut Frame, area: Rect) { pub fn render(state: &mut State, frame: &mut Frame, area: Rect) {
match state.savefile() { match state.savefile() {
Some(savefile) => render_info(savefile, frame, area), Some(savefile) => render_info(savefile, state, frame, area),
None => render_no_active_file(frame, area), None => render_no_active_file(frame, area),
} }
} }
@ -26,7 +28,7 @@ fn render_no_active_file(frame: &mut Frame, area: Rect) {
} }
fn render_info(savefile: &Savefile, mut frame: &mut Frame, area: Rect) { fn render_info(savefile: &Savefile, state: &State, mut frame: &mut Frame, area: Rect) {
let columns = Layout::default() let columns = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)]) .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
@ -46,18 +48,23 @@ fn render_info(savefile: &Savefile, mut frame: &mut Frame, area: Rect) {
.constraints([Constraint::Ratio(10, 10)]) .constraints([Constraint::Ratio(10, 10)])
.split(columns[1]); .split(columns[1]);
render_stats(&savefile, state, &mut frame, left_column[0]);
render_stats(&savefile, &mut frame, left_column[0]); render_glyphs(&savefile, state, &mut frame, left_column[1]);
render_glyphs(&savefile, &mut frame, left_column[1]); render_murals(&savefile, state, &mut frame, left_column[2]);
render_murals(&savefile, &mut frame, left_column[2]); render_companions(&savefile, state, &mut frame, right_column[0]);
render_companions(&savefile, &mut frame, right_column[0]);
} }
fn render_stats<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) { fn render_stats<'a>(savefile: &Savefile, state: &State, frame: &mut Frame, area: Rect) {
let border_style = if state.active_section == Section::General && state.mode == Mode::Edit {
Style::default().fg(ratatui::style::Color::Blue)
} else {
Style::default()
};
let stats_section_block = Block::default() let stats_section_block = Block::default()
.padding(Padding::new(2, 2, 1, 1)) .padding(Padding::new(2, 2, 1, 1))
.border_style(border_style)
.borders(Borders::ALL); .borders(Borders::ALL);
let layout = Layout::default() let layout = Layout::default()
@ -107,10 +114,17 @@ fn render_stats<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) {
} }
fn render_companions<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) { fn render_companions<'a>(savefile: &Savefile, state: &State, frame: &mut Frame, area: Rect) {
let border_style = if state.active_section == Section::Companions && state.mode == Mode::Edit {
Style::default().fg(ratatui::style::Color::Blue)
} else {
Style::default()
};
let companions_block = Block::default() let companions_block = Block::default()
.title("Companions") .title("Companions")
.padding(Padding::new(2, 2, 1, 1)) .padding(Padding::new(2, 2, 1, 1))
.border_style(border_style)
.borders(Borders::ALL); .borders(Borders::ALL);
let layout = Layout::default() let layout = Layout::default()
@ -150,12 +164,19 @@ fn render_companions<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) {
} }
fn render_glyphs<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) { fn render_glyphs<'a>(savefile: &Savefile, state: &State, frame: &mut Frame, area: Rect) {
const FOUND_SIGN: &str = ""; const FOUND_SIGN: &str = "";
const NOT_FOUND_SIGN: &str = ""; const NOT_FOUND_SIGN: &str = "";
let border_style = if state.active_section == Section::Glyphs && state.mode == Mode::Edit {
Style::default().fg(ratatui::style::Color::Blue)
} else {
Style::default()
};
let block = Block::default() let block = Block::default()
.title("Glyphs") .title("Glyphs")
.border_style(border_style)
.borders(Borders::ALL) .borders(Borders::ALL)
.padding(Padding::new(2, 2, 1, 1)); .padding(Padding::new(2, 2, 1, 1));
@ -183,12 +204,19 @@ fn render_glyphs<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) {
} }
fn render_murals<'a>(savefile: &Savefile, frame: &mut Frame, area: Rect) { fn render_murals<'a>(savefile: &Savefile, state: &State, frame: &mut Frame, area: Rect) {
const FOUND_SIGN: &str = ""; const FOUND_SIGN: &str = "";
const NOT_FOUND_SIGN: &str = ""; const NOT_FOUND_SIGN: &str = "";
let border_style = if state.active_section == Section::Murals && state.mode == Mode::Edit {
Style::default().fg(ratatui::style::Color::Blue)
} else {
Style::default()
};
let block = Block::default() let block = Block::default()
.title("Murals") .title("Murals")
.border_style(border_style)
.borders(Borders::ALL) .borders(Borders::ALL)
.padding(Padding::new(2, 2, 1, 1)); .padding(Padding::new(2, 2, 1, 1));

View File

@ -17,6 +17,14 @@ pub fn render(state: &State, mut frame: &mut Frame, area: Rect) {
frame.render_widget(error_msg, area); frame.render_widget(error_msg, area);
} }
Mode::Edit => {
if let Some(savefile) = state.savefile() {
let text = format!("Editing file: {}", savefile.path.display());
let status = Paragraph::new(text).block(status_block);
frame.render_widget(status, area);
}
}
#[cfg(feature = "watch")] #[cfg(feature = "watch")]
Mode::Normal if state.is_watching_file() => { Mode::Normal if state.is_watching_file() => {
if let Some(savefile) = state.savefile() { if let Some(savefile) = state.savefile() {