From fe0938b1de0c46fc2afcaa3dcd6a0f4ec870d21a Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Fri, 2 Aug 2024 00:36:10 +0200 Subject: add state which is shared with the lua environment --- src/widgets/sheetview/mod.rs | 141 ++++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 69 deletions(-) (limited to 'src/widgets/sheetview/mod.rs') diff --git a/src/widgets/sheetview/mod.rs b/src/widgets/sheetview/mod.rs index f81edab..4ae37f0 100644 --- a/src/widgets/sheetview/mod.rs +++ b/src/widgets/sheetview/mod.rs @@ -10,13 +10,14 @@ use ratatui::{ use crate::{ config::GlobalConfig, + cursor::CursorMove, lua, sheet::{ cell::Cell, eval::EvalFunction, - register::{Register, SheetId}, Sheet, }, + state::GlobalState, }; use super::{luaeditor::LuaEditor, statusbar::StatusBar}; @@ -39,8 +40,6 @@ enum SheetViewMode { #[derive(Default)] pub struct SheetView { bar: StatusBar, - sheet: SheetId, - cursor: (u16, u16), scroll: (u16, u16), selection_anchor: Option<(u16, u16)>, mode: SheetViewMode, @@ -48,7 +47,7 @@ pub struct SheetView { } impl SheetView { - pub fn new(sheet: SheetId) -> Self { + pub fn new() -> Self { Self { bar: StatusBar::new() .left(" NORMAL ") @@ -56,8 +55,6 @@ impl SheetView { .middle("Sheet") .right("") .right_style(Style::default().on_red()), - sheet, - cursor: (0, 0), scroll: (0, 0), mode: SheetViewMode::Normal, selection_anchor: None, @@ -65,21 +62,12 @@ impl SheetView { } } - pub fn sheet(mut self, sheet: SheetId) -> Self { - self.sheet = sheet; - self - } - - pub fn move_cursor_by(&mut self, delta: (i32, i32)) { - let lock = Register::get(self.sheet).unwrap(); - let sheet = lock.read().unwrap(); - - self.cursor.0 = ((self.cursor.0 as i32) + delta.0) - .max(0) - .min(sheet.height() as i32 - 1) as u16; - self.cursor.1 = ((self.cursor.1 as i32) + delta.1) - .max(0) - .min(sheet.width() as i32 - 1) as u16; + pub fn move_cursor_by(&mut self, delta: (isize, isize)) { + let mut state = GlobalState::instance_mut(); + state + .sheetview + .cursor + .move_checked(CursorMove::Relative(delta)); } pub fn selection(&self) -> Vec<(u16, u16)> { @@ -108,17 +96,19 @@ impl SheetView { } fn selection_range(&self) -> Option<((u16, u16), (u16, u16))> { + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; if let Some(selection) = self.selection_anchor { - let row = if selection.0 > self.cursor.0 { - (self.cursor.0, selection.0) + let row = if selection.0 as usize > cursor.y() { + (cursor.y() as u16, selection.0) } else { - (selection.0, self.cursor.0) + (selection.0, cursor.y() as u16) }; - let column = if selection.1 > self.cursor.1 { - (self.cursor.1, selection.1) + let column = if selection.1 as usize > cursor.x() { + (cursor.x() as u16, selection.1) } else { - (selection.1, self.cursor.1) + (selection.1, cursor.x() as u16) }; Some((row, column)) @@ -133,7 +123,9 @@ impl SheetView { if handle.is_finished() { match handle.join().unwrap() { Ok(sheet) => { - Register::get(self.sheet) + GlobalState::instance() + .sheetview + .active_sheet() .unwrap() .write() .unwrap() @@ -151,12 +143,14 @@ impl SheetView { pub fn handle_key_event(&mut self, event: KeyEvent) { match &self.mode { SheetViewMode::Normal => match event.code { - KeyCode::Char('j') => self.move_cursor_by((1, 0)), - KeyCode::Char('k') => self.move_cursor_by((-1, 0)), - KeyCode::Char('h') => self.move_cursor_by((0, -1)), - KeyCode::Char('l') => self.move_cursor_by((0, 1)), + KeyCode::Char('j') => self.move_cursor_by((0, 1)), + KeyCode::Char('k') => self.move_cursor_by((0, -1)), + KeyCode::Char('h') => self.move_cursor_by((-1, 0)), + KeyCode::Char('l') => self.move_cursor_by((1, 0)), KeyCode::Char('v') => { - self.selection_anchor = Some(self.cursor); + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; + self.selection_anchor = Some((cursor.y() as u16, cursor.x() as u16)); self.mode = SheetViewMode::Visual } KeyCode::Char('s') => { @@ -175,13 +169,16 @@ impl SheetView { }, SheetViewMode::Insert => match event.code { KeyCode::Enter => { - let lock = Register::get(self.sheet).unwrap(); + let lock = GlobalState::instance().sheetview.active_sheet().unwrap(); let mut sheet = lock.write().unwrap(); + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; + if self.selection_anchor.is_some() { self.selection().iter().map(|(r, c)| (*r, *c)).collect() } else { - vec![self.cursor] + vec![(cursor.y() as u16, cursor.x() as u16)] } .into_iter() .for_each(|(r, c)| { @@ -212,10 +209,10 @@ impl SheetView { _ => self.bar.handle_keyevent(event), }, SheetViewMode::Visual => match event.code { - KeyCode::Char('j') => self.move_cursor_by((1, 0)), - KeyCode::Char('k') => self.move_cursor_by((-1, 0)), - KeyCode::Char('h') => self.move_cursor_by((0, -1)), - KeyCode::Char('l') => self.move_cursor_by((0, 1)), + KeyCode::Char('j') => self.move_cursor_by((0, 1)), + KeyCode::Char('k') => self.move_cursor_by((0, -1)), + KeyCode::Char('h') => self.move_cursor_by((-1, 0)), + KeyCode::Char('l') => self.move_cursor_by((1, 0)), KeyCode::Esc | KeyCode::Char('v') => { self.selection_anchor = None; self.mode = SheetViewMode::Normal; @@ -265,7 +262,7 @@ impl SheetView { let script = self.editor.text(); let (width, height) = { - let lock = Register::get(self.sheet).unwrap(); + let lock = GlobalState::instance().sheetview.active_sheet().unwrap(); let sheet = lock.read().unwrap(); (sheet.width(), sheet.height()) }; @@ -287,7 +284,9 @@ impl SheetView { } self.mode = SheetViewMode::Processing(Some( - Register::get(self.sheet) + GlobalState::instance() + .sheetview + .active_sheet() .unwrap() .eval_function(script, cells), )); @@ -383,9 +382,12 @@ impl Widget for &mut SheetView { ); { - let lock = Register::get(self.sheet).unwrap(); + let lock = GlobalState::instance().sheetview.active_sheet().unwrap(); let sheet = lock.read().unwrap(); + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; + let mut sheet_area_inner = self.bar.area(sheet_area); if self.is_editor_visible() { @@ -397,16 +399,16 @@ impl Widget for &mut SheetView { .width() .min((sheet_area_inner.width / DEFAULT_COLUMN_WIDTH) as usize); - if self.cursor.0 >= viewport_rows as u16 + self.scroll.0 { - self.scroll.0 = self.cursor.0 - viewport_rows as u16 + 1; - } else if self.cursor.0 < self.scroll.0 { - self.scroll.0 = self.cursor.0; + if cursor.y() >= viewport_rows + self.scroll.0 as usize { + self.scroll.0 = (cursor.y() - viewport_rows) as u16 + 1; + } else if cursor.y() < self.scroll.0 as usize { + self.scroll.0 = cursor.y() as u16; } - if self.cursor.1 >= viewport_columns as u16 + self.scroll.1 { - self.scroll.1 = self.cursor.1 - viewport_columns as u16 + 1; - } else if self.cursor.1 < self.scroll.1 { - self.scroll.1 = self.cursor.1; + if cursor.x() >= viewport_columns + self.scroll.1 as usize { + self.scroll.1 = (cursor.x() - viewport_columns) as u16 + 1; + } else if cursor.x() < self.scroll.1 as usize { + self.scroll.1 = cursor.x() as u16; } for row in 0..viewport_rows as u16 { @@ -417,25 +419,26 @@ impl Widget for &mut SheetView { { let cell = cell_ref.value().to_string() + " "; - let line = if (cell_pos_y, cell_pos_x) == self.cursor { - theme - .cursor - .get(cell_ref, &lua::get()) - .unwrap_or_default() - .apply(cell.to_line()) - } else if self.is_in_selection(cell_pos_y, cell_pos_x) { - theme - .selection - .get(cell_ref, &lua::get()) - .unwrap_or_default() - .apply(cell.to_line()) - } else { - theme - .cell - .get(cell_ref, &lua::get()) - .unwrap_or_default() - .apply(cell.to_line()) - }; + let line = + if (cell_pos_y, cell_pos_x) == (cursor.y() as u16, cursor.x() as u16) { + theme + .cursor + .get(cell_ref, &lua::get()) + .unwrap_or_default() + .apply(cell.to_line()) + } else if self.is_in_selection(cell_pos_y, cell_pos_x) { + theme + .selection + .get(cell_ref, &lua::get()) + .unwrap_or_default() + .apply(cell.to_line()) + } else { + theme + .cell + .get(cell_ref, &lua::get()) + .unwrap_or_default() + .apply(cell.to_line()) + }; let rect = Rect::new( sheet_area_inner.x + column * DEFAULT_COLUMN_WIDTH, -- cgit v1.2.3-70-g09d2