diff --git a/src/app/app.rs b/src/app/app.rs index bbbda5e..d86f7f6 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -5,10 +5,10 @@ use ratatui::{DefaultTerminal, Frame, crossterm::event, layout::{self, Constrain use crate::app::{calc::{Grid, LEN}, mode::Mode}; pub struct App { - exit: bool, + pub exit: bool, pub grid: Grid, pub mode: Mode, - file: Option, + pub file: Option, } impl Widget for &App { @@ -18,7 +18,6 @@ impl Widget for &App { let cell_height = 1; let cell_length = 5; - let x_max = if area.width / cell_length > len { len - 1 } else { @@ -30,14 +29,41 @@ impl Widget for &App { area.height / cell_height }; + let is_selected = |x: usize, y: usize| -> bool { + if let Mode::Visual((mut x1, mut y1)) = self.mode { + let (mut x2, mut y2) = self.grid.selected_cell; + x1 += 1; + y1 += 1; + x2 += 1; + y2 += 1; + + + + if x >= x1 && x <= x2{ + // in-between the Xs + if y >= y1 && y <= y2 { + // in-between the Ys + return true + } + } + + } + false + }; + for x in 0..x_max { for y in 0..y_max { let mut display = String::new(); let mut style = Style::new().fg(Color::White); + if is_selected(x.into(),y.into()) { + style = style.fg(Color::LightMagenta).bg(Color::Blue); + } + const ORANGE1: Color = Color::Rgb(200, 160, 0); const ORANGE2: Color = Color::Rgb(180, 130, 0); + match (x == 0, y == 0) { (true, true) => { let (x,y) = self.grid.selected_cell; @@ -159,7 +185,7 @@ impl App { }), layout[0], ), - Mode::Visual(start_pos) => {} + Mode::Visual(_) => {} } frame.render_widget(self, layout[1]); @@ -172,32 +198,7 @@ impl App { event::Event::Key(key) => match key.code { event::KeyCode::Esc => self.mode = Mode::Normal, event::KeyCode::Char(c) => { - chord.add_char(c); - match chord.as_string()[0..chord.as_string().len() - 1].parse::() { - Ok(num) => match c { - 'G' => { - let sel = self.grid.selected_cell; - self.grid.selected_cell = (sel.0, num); - self.mode = Mode::Normal; - } - _ => { - if c.is_alphabetic() { - self.mode = Mode::Normal; - for _ in 0..num { - Mode::process_key(self, c); - } - } - } - }, - Err(_) => match chord.as_string().as_str() { - "d " | "dw" => { - let loc = self.grid.selected_cell; - self.grid.set_cell_raw(loc, String::new()); - self.mode = Mode::Normal; - } - _ => {} - }, - } + Mode::process_key(self, c); } event::KeyCode::Backspace => { chord.backspace(); @@ -243,12 +244,11 @@ impl App { }, _ => todo!(), }, - Mode::Visual(start_pos) => { + Mode::Visual(_start_pos) => { if let event::Event::Key(key) = event::read()? { match key.code { event::KeyCode::Char(c) => { Mode::process_key(self, c); - todo!(); } event::KeyCode::Esc => self.mode = Mode::Normal, _ => {} @@ -262,12 +262,7 @@ impl App { self.mode = Mode::Normal; } event::KeyCode::Enter => { - // [':', 'q'] - match editor.as_string().as_bytes()[1] as char { - 'w' => {} - 'q' => self.exit = true, - _ => {} - } + Mode::process_cmd(self); self.mode = Mode::Normal; } event::KeyCode::Backspace => { diff --git a/src/app/mode.rs b/src/app/mode.rs index 14ef942..123dde8 100644 --- a/src/app/mode.rs +++ b/src/app/mode.rs @@ -6,7 +6,7 @@ use ratatui::{ widgets::{Paragraph, Widget}, }; -use crate::app::app::App; +use crate::app::{self, app::App}; pub enum Mode { Insert(Editor), @@ -35,52 +35,107 @@ impl Display for Mode { } impl Mode { - pub fn process_key(app: &mut App, key: char) { - match key { - // < - 'h' => { - app.grid.selected_cell.0 = app.grid.selected_cell.0.saturating_sub(1); - return; - } - // v - 'j' => { - app.grid.selected_cell.1 = app.grid.selected_cell.1.saturating_add(1); - return; - } - // ^ - 'k' => { - app.grid.selected_cell.1 = app.grid.selected_cell.1.saturating_sub(1); - return; - } - // > - 'l' => { - app.grid.selected_cell.0 = app.grid.selected_cell.0.saturating_add(1); - return; - } - _ => {} - } - - if let Mode::Normal = app.mode { - match key { - // edit cell - 'i' | 'a' => { - let (x, y) = app.grid.selected_cell; - - let val = app.grid.get_cell_raw(x, y).as_ref().map(|f| f.as_raw_string()).unwrap_or(String::new()); - - app.mode = Mode::Insert(Editor::new(val, (x, y))); + pub fn process_cmd(app: &mut App) { + if let Mode::Command(editor) = &mut app.mode { + // [':', 'q'] + match editor.as_string().as_bytes()[1] as char { + 'w' => { + if let Some(file) = &app.file { + unimplemented!("Figure out how we want to save Grid to a csv or something") + } else { + // TODO figure out how to get an error message to the user + } } - 'I' => { /* insert col before */ } - 'A' => { /* insert col after */ } - 'o' => { /* insert row below */ } - 'O' => { /* insert row above */ } - 'v' => app.mode = Mode::Visual(app.grid.selected_cell), - ':' => app.mode = Mode::Command(Chord::new(':')), - // loose chars will put you into chord mode - c => app.mode = Mode::Chord(Chord::new(c)), + 'q' => app.exit = true, + _ => {} } } } + + pub fn process_key(app: &mut App, key: char) { + match &mut app.mode { + // FIXME this will break visual movement + Mode::Normal => { + match key { + // < + 'h' => { + app.grid.selected_cell.0 = app.grid.selected_cell.0.saturating_sub(1); + return; + } + // v + 'j' => { + app.grid.selected_cell.1 = app.grid.selected_cell.1.saturating_add(1); + return; + } + // ^ + 'k' => { + app.grid.selected_cell.1 = app.grid.selected_cell.1.saturating_sub(1); + return; + } + // > + 'l' => { + app.grid.selected_cell.0 = app.grid.selected_cell.0.saturating_add(1); + return; + } + '0' => { + app.grid.selected_cell.0 = 0; + return; + } + // edit cell + 'i' | 'a' => { + let (x, y) = app.grid.selected_cell; + + let val = + app.grid.get_cell_raw(x, y).as_ref().map(|f| f.as_raw_string()).unwrap_or(String::new()); + + app.mode = Mode::Insert(Editor::new(val, (x, y))); + } + 'I' => { /* insert col before */ } + 'A' => { /* insert col after */ } + 'o' => { /* insert row below */ } + 'O' => { /* insert row above */ } + 'v' => app.mode = Mode::Visual(app.grid.selected_cell), + ':' => app.mode = Mode::Command(Chord::new(':')), + // loose chars will put you into chord mode + c => app.mode = Mode::Chord(Chord::new(c)), + } + } + Mode::Chord(chord) => { + chord.add_char(key); + match chord.as_string()[0..chord.as_string().len() - 1].parse::() { + // For chords that can take a numeric input + Ok(num) => match key { + 'G' => { + let sel = app.grid.selected_cell; + app.grid.selected_cell = (sel.0, num); + app.mode = Mode::Normal; + } + _ => { + if key.is_alphabetic() { + app.mode = Mode::Normal; + for _ in 0..num { + Mode::process_key(app, key); + } + } + } + }, + Err(_) => match chord.as_string().as_str() { + "d " | "dw" => { + let loc = app.grid.selected_cell; + app.grid.set_cell_raw(loc, String::new()); + app.mode = Mode::Normal; + } + "gg" => { + app.grid.selected_cell.1 = 0; + app.mode = Mode::Normal; + } + _ => {} + }, + } + } + _ => todo!(), + } + } } pub struct Editor {