Implement section selection for edit mode
This commit is contained in:
parent
ccf7376637
commit
7eaabc0f63
@ -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 |
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)?;
|
||||||
|
@ -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,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user