From 91fb658f65f1018c9432e34d802993ea8cf86d60 Mon Sep 17 00:00:00 2001 From: Rushmore75 Date: Fri, 23 Jan 2026 11:17:43 -0700 Subject: [PATCH] close #24 --- src/app/app.rs | 6 ++-- src/app/mode.rs | 40 ++++++++++++++++++++++ src/app/screen.rs | 84 ++++++++++++++++++++++++++--------------------- 3 files changed, 91 insertions(+), 39 deletions(-) diff --git a/src/app/app.rs b/src/app/app.rs index acc5e96..8c3c7a4 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -18,7 +18,7 @@ use ratatui::{ use crate::app::{ clipboard::Clipboard, error_msg::StatusMessage, - logic::{calc::Grid, cell::CellType}, + logic::{self, calc::Grid, cell::CellType}, mode::Mode, screen::ScreenSpace, }; @@ -66,7 +66,9 @@ impl Widget for &App { let mut style = Style::new().fg(Color::White); // Custom width for the header of each row - let row_header_width: u16 = 4; + let row_header_width: u16 = logic::calc::LEN.to_string().len() as u16; + // ^^ Feels like it oculd be static but evaluating string lens doesn't work at + // compile time. Thus cannot be static. let cell_width = self.screen.get_cell_width(&self.vars) as u16; let cell_height = self.screen.get_cell_height(&self.vars) as u16; diff --git a/src/app/mode.rs b/src/app/mode.rs index 8ea6d13..c28f8ef 100644 --- a/src/app/mode.rs +++ b/src/app/mode.rs @@ -266,6 +266,18 @@ impl Mode { app.grid.mv_cursor_to(0, y); return; } + // Go to end of row + '$' => { + let (_, y) = app.grid.cursor(); + app.grid.mv_cursor_to(super::logic::calc::LEN, y); + return; + } + // Go to bottom of column + 'G' => { + let (x, _) = app.grid.cursor(); + app.grid.mv_cursor_to(x, super::logic::calc::LEN,); + return; + } // edit cell 'i' | 'a' => { let (x, y) = app.grid.cursor(); @@ -379,6 +391,34 @@ impl Mode { app.grid.mv_cursor_to(x, 0); app.mode = Mode::Normal; } + // Go to the bottom of the current window + ("g", 'G') => { + let (x, _) = app.grid.cursor(); + let (_, y_height) = app.screen.get_screen_size(&app.vars); + let y_origin = app.screen.scroll_y(); + + app.grid.mv_cursor_to(x, y_origin+y_height); + app.mode = Mode::Normal; + return; + } + // Go to the right edge of the current window + ("g", '$') => { + let (_, y) = app.grid.cursor(); + let (x_width, _) = app.screen.get_screen_size(&app.vars); + let x_origin = app.screen.scroll_x(); + + app.grid.mv_cursor_to(x_origin+x_width, y); + app.mode = Mode::Normal; + } + // Go to the left edge of the current window + ("g", '0') => { + let (_, y) = app.grid.cursor(); + let x_origin = app.screen.scroll_x(); + + app.grid.mv_cursor_to(x_origin, y); + app.mode = Mode::Normal; + return; + } // center screen to cursor ("z", 'z') => { app.screen.center_x(app.grid.cursor(), &app.vars); diff --git a/src/app/screen.rs b/src/app/screen.rs index a0089ce..7d76d36 100644 --- a/src/app/screen.rs +++ b/src/app/screen.rs @@ -5,9 +5,12 @@ use ratatui::prelude; use crate::app::logic::calc::LEN; pub struct ScreenSpace { - /// This is measured in cells + /// This is measured in cells. + /// This is the top-left cell index. scroll: (usize, usize), + /// In chars default_cell_len: usize, + /// In chars default_cell_hight: usize, /// This is measured in chars last_seen_screen_size: RwLock<(usize, usize)> @@ -24,58 +27,65 @@ impl ScreenSpace { } pub fn center_x(&mut self, (cursor_x, _): (usize, usize), vars: &HashMap) { - if let Ok(screen_size) = self.last_seen_screen_size.read() { - let x_cells = (screen_size.0 / self.get_cell_width(vars) as usize) -2; - let x_center = self.scroll_x() + (x_cells/2); + let (x_cells, _) = self.get_screen_size(vars); + let x_center = self.scroll_x() + (x_cells/2); - let delta = cursor_x as isize - x_center as isize; - self.scroll.0 = self.scroll.0.saturating_add_signed(delta); - } + let delta = cursor_x as isize - x_center as isize; + self.scroll.0 = self.scroll.0.saturating_add_signed(delta); } pub fn center_y(&mut self, (_, cursor_y): (usize, usize), vars: &HashMap) { - if let Ok(screen_size) = self.last_seen_screen_size.read() { - let y_cells = (screen_size.1 / self.get_cell_height(vars) as usize) -2; - let y_center = self.scroll_y() + (y_cells/2); + let (_, y_cells) = self.get_screen_size(vars); + let y_center = self.scroll_y() + (y_cells/2); - let delta = cursor_y as isize - y_center as isize; - self.scroll.1 = self.scroll.1.saturating_add_signed(delta); - } + let delta = cursor_y as isize - y_center as isize; + self.scroll.1 = self.scroll.1.saturating_add_signed(delta); } - - pub fn scroll_based_on_cursor_location(&mut self, (cursor_x, cursor_y): (usize, usize), vars: &HashMap) { + + /// In chars + pub fn get_screen_size(&self, vars: &HashMap) -> (usize, usize) { if let Ok(screen_size) = self.last_seen_screen_size.read() { // ======= X ======= // screen seems to be 2 cells smaller than it should be // this is probably related to issue #6 let x_cells = (screen_size.0 / self.get_cell_width(vars) as usize) -2; - let lower_x = self.scroll_x(); - let upper_x = self.scroll_x() + x_cells; - - if cursor_x < lower_x { - let delta = lower_x - cursor_x; - self.scroll.0 = self.scroll.0.saturating_sub(delta); - } - if cursor_x > upper_x { - let delta = cursor_x - upper_x; - self.scroll.0 = self.scroll.0.saturating_add(delta); - } - // ======= Y ======= // screen seems to be 2 cells smaller than it should be // this is probably related to issue #6 let y_cells = (screen_size.1 / self.get_cell_height(vars) as usize) -2; - let lower_y = self.scroll_y(); - let upper_y = self.scroll_y() + y_cells; + (x_cells,y_cells) + } else { + (0,0) + } + } - if cursor_y < lower_y { - let delta = lower_y - cursor_y; - self.scroll.1 = self.scroll.1.saturating_sub(delta); - } + pub fn scroll_based_on_cursor_location(&mut self, (cursor_x, cursor_y): (usize, usize), vars: &HashMap) { + let (x_cells, y_cells) = self.get_screen_size(vars); - if cursor_y > upper_y { - let delta = cursor_y - upper_y; - self.scroll.1 = self.scroll.1.saturating_add(delta); - } + + let lower_x = self.scroll_x(); + let upper_x = self.scroll_x() + x_cells; + + if cursor_x < lower_x { + let delta = lower_x - cursor_x; + self.scroll.0 = self.scroll.0.saturating_sub(delta); + } + if cursor_x > upper_x { + let delta = cursor_x - upper_x; + self.scroll.0 = self.scroll.0.saturating_add(delta); + } + + + let lower_y = self.scroll_y(); + let upper_y = self.scroll_y() + y_cells; + + if cursor_y < lower_y { + let delta = lower_y - cursor_y; + self.scroll.1 = self.scroll.1.saturating_sub(delta); + } + + if cursor_y > upper_y { + let delta = cursor_y - upper_y; + self.scroll.1 = self.scroll.1.saturating_add(delta); } }