fix scrolling
This commit is contained in:
@@ -63,7 +63,7 @@ impl Widget for &App {
|
|||||||
x_idx = x as usize - 1 + self.screen.scroll_x();
|
x_idx = x as usize - 1 + self.screen.scroll_x();
|
||||||
}
|
}
|
||||||
if y != 0 {
|
if y != 0 {
|
||||||
y_idx = y as usize - 1 + self.screen.y();
|
y_idx = y as usize - 1 + self.screen.scroll_y();
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_selected(x.into(), y.into()) {
|
if is_selected(x.into(), y.into()) {
|
||||||
@@ -216,7 +216,7 @@ impl App {
|
|||||||
frame.render_widget(Paragraph::new(format!("x/w y/h: cursor{:?} scroll({}, {}) cell({}, {}) screen({}, {})",
|
frame.render_widget(Paragraph::new(format!("x/w y/h: cursor{:?} scroll({}, {}) cell({}, {}) screen({}, {})",
|
||||||
self.grid.selected_cell,
|
self.grid.selected_cell,
|
||||||
self.screen.scroll_x(),
|
self.screen.scroll_x(),
|
||||||
self.screen.y(),
|
self.screen.scroll_y(),
|
||||||
self.screen.get_cell_width(&self.vars),
|
self.screen.get_cell_width(&self.vars),
|
||||||
self.screen.get_cell_height(&self.vars),
|
self.screen.get_cell_height(&self.vars),
|
||||||
body.width,
|
body.width,
|
||||||
@@ -225,9 +225,6 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_events(&mut self) -> io::Result<()> {
|
fn handle_events(&mut self) -> io::Result<()> {
|
||||||
// make sure cursor is inside window
|
|
||||||
self.screen.scroll_based_on_cursor_location(self.grid.selected_cell, &self.vars);
|
|
||||||
|
|
||||||
match &mut self.mode {
|
match &mut self.mode {
|
||||||
Mode::Chord(chord) => match event::read()? {
|
Mode::Chord(chord) => match event::read()? {
|
||||||
event::Event::Key(key) => match key.code {
|
event::Event::Key(key) => match key.code {
|
||||||
@@ -312,6 +309,9 @@ impl App {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure cursor is inside window
|
||||||
|
self.screen.scroll_based_on_cursor_location(self.grid.selected_cell, &self.vars);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,27 +25,45 @@ impl ScreenSpace {
|
|||||||
|
|
||||||
pub fn scroll_based_on_cursor_location(&mut self, (cursor_x, cursor_y): (usize, usize), vars: &HashMap<String, String>) {
|
pub fn scroll_based_on_cursor_location(&mut self, (cursor_x, cursor_y): (usize, usize), vars: &HashMap<String, String>) {
|
||||||
if let Ok(screen_size) = self.last_seen_screen_size.read() {
|
if let Ok(screen_size) = self.last_seen_screen_size.read() {
|
||||||
|
// ======= X =======
|
||||||
// screen seems to be 2 cells smaller than it should be
|
let x_cells = (screen_size.0) / self.get_cell_width(vars) as usize ;
|
||||||
let x_cells = (screen_size.0 / self.get_cell_width(vars) as usize)-2;
|
|
||||||
|
|
||||||
let lower_x = self.scroll_x();
|
let lower_x = self.scroll_x();
|
||||||
let upper_x = self.scroll_x() + x_cells;
|
// screen seems to be 2 cells smaller than it should be
|
||||||
|
let upper_x = self.scroll_x() + x_cells -2;
|
||||||
|
|
||||||
if cursor_x<=lower_x {
|
if cursor_x < lower_x {
|
||||||
self.scroll.0 = self.scroll.0.saturating_sub(1);
|
let delta = lower_x - cursor_x;
|
||||||
|
self.scroll.0 = self.scroll.0.saturating_sub(delta);
|
||||||
}
|
}
|
||||||
if cursor_x > upper_x {
|
if cursor_x > upper_x {
|
||||||
self.scroll.0 = self.scroll.0.saturating_add(1);
|
let delta = cursor_x - upper_x;
|
||||||
|
self.scroll.0 = self.scroll.0.saturating_add(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ======= Y =======
|
||||||
|
let y_cells = screen_size.1 / self.get_cell_height(vars) as usize;
|
||||||
|
|
||||||
|
let lower_y = self.scroll_y();
|
||||||
|
// screen seems to be 2 cells smaller than it should be
|
||||||
|
let upper_y = self.scroll_y() + y_cells -2;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_x(&self) -> usize {
|
pub fn scroll_x(&self) -> usize {
|
||||||
self.scroll.0
|
self.scroll.0
|
||||||
}
|
}
|
||||||
pub fn y(&self) -> usize{
|
pub fn scroll_y(&self) -> usize{
|
||||||
self.scroll.1
|
self.scroll.1
|
||||||
}
|
}
|
||||||
pub fn get_cell_height(&self, vars: &HashMap<String, String>) -> usize {
|
pub fn get_cell_height(&self, vars: &HashMap<String, String>) -> usize {
|
||||||
@@ -78,3 +96,54 @@ impl ScreenSpace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fit_cells() {
|
||||||
|
use crate::App;
|
||||||
|
let mut app = App::new();
|
||||||
|
app.vars.insert("length".to_string(), 10.to_string());
|
||||||
|
app.vars.insert("height".to_string(), 1.to_string());
|
||||||
|
|
||||||
|
let (x,y) = app.screen.how_many_cells_fit_in(&Rect::new(0, 0, 181, 14), &app.vars);
|
||||||
|
assert_eq!(x, 18);
|
||||||
|
assert_eq!(y, 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn scroll() {
|
||||||
|
use crate::App;
|
||||||
|
let mut app = App::new();
|
||||||
|
app.vars.insert("length".to_string(), 10.to_string());
|
||||||
|
app.vars.insert("height".to_string(), 1.to_string());
|
||||||
|
|
||||||
|
// We have to check how many cells fit, because screen learns the width
|
||||||
|
// of the area by rumour here.
|
||||||
|
let (x,y) = app.screen.how_many_cells_fit_in(&Rect::new(0, 0, 181, 14), &app.vars);
|
||||||
|
assert_eq!(x, 18);
|
||||||
|
assert_eq!(y, 14);
|
||||||
|
|
||||||
|
// we aren't scrolled at all yet
|
||||||
|
app.screen.scroll_based_on_cursor_location((0,0), &app.vars);
|
||||||
|
assert_eq!(app.screen.scroll.0, 0);
|
||||||
|
assert_eq!(app.screen.scroll.1, 0);
|
||||||
|
|
||||||
|
// at the edge of visible, but shouldn't scroll yet
|
||||||
|
app.screen.scroll_based_on_cursor_location((18,0), &app.vars);
|
||||||
|
assert_eq!(app.screen.scroll.0, 0);
|
||||||
|
assert_eq!(app.screen.scroll.1, 0);
|
||||||
|
|
||||||
|
// scroll 1 right
|
||||||
|
app.screen.scroll_based_on_cursor_location((19,0), &app.vars);
|
||||||
|
assert_eq!(app.screen.scroll.0, 1);
|
||||||
|
assert_eq!(app.screen.scroll.1, 0);
|
||||||
|
|
||||||
|
// cursor comes back, scroll should stay
|
||||||
|
app.screen.scroll_based_on_cursor_location((18,0), &app.vars);
|
||||||
|
assert_eq!(app.screen.scroll.0, 1);
|
||||||
|
assert_eq!(app.screen.scroll.1, 0);
|
||||||
|
|
||||||
|
// scroll left
|
||||||
|
app.screen.scroll_based_on_cursor_location((0,0), &app.vars);
|
||||||
|
assert_eq!(app.screen.scroll.0, 0);
|
||||||
|
assert_eq!(app.screen.scroll.1, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user