From fa5c2c2d58e2becbec23e792dd2cd25fdc0ac616 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 14 Dec 2024 07:49:00 -0500 Subject: [PATCH] fix: Only show range selection when in range-select mode --- src/ui/mod.rs | 70 +++++++++++++-------------------------- src/ui/render/mod.rs | 29 ++++++++++++---- src/ui/render/test.rs | 8 ++--- src/ui/render/viewport.rs | 8 +++-- 4 files changed, 54 insertions(+), 61 deletions(-) diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 385d8d3..d013e9a 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -564,13 +564,13 @@ impl<'ws> Workspace<'ws> { .contains(KeyModifiers::CONTROL | KeyModifiers::SHIFT) => { // TODO(zaphar): Share the algorithm below between both copies - self.copy_range_formatted()?; + self.copy_range(true)?; } - KeyCode::Char('Y') => self.copy_range_formatted()?, + KeyCode::Char('Y') => self.copy_range(true)?, KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => { - self.copy_range_contents()?; + self.copy_range(false)?; } - KeyCode::Char('y') => self.copy_range_contents()?, + KeyCode::Char('y') => self.copy_range(false)?, _ => { // moop } @@ -579,7 +579,7 @@ impl<'ws> Workspace<'ws> { Ok(None) } - fn copy_range_formatted(&mut self) -> Result<(), anyhow::Error> { + fn copy_range(&mut self, formatted: bool) -> Result<(), anyhow::Error> { self.update_range_selection()?; match &self.state.range_select.get_range() { Some(( @@ -596,55 +596,26 @@ impl<'ws> Workspace<'ws> { for ri in (*row_start)..=(*row_end) { let mut cols = Vec::new(); for ci in (*col_start)..=(*col_end) { - cols.push( + cols.push(if formatted { self.book - .get_cell_addr_rendered(&Address { row: ri, col: ci })?, - ); + .get_cell_addr_rendered(&Address { row: ri, col: ci })? + } else { + self.book + .get_cell_addr_contents(&Address { row: ri, col: ci })? + }); } rows.push(cols); } self.state.clipboard = Some(ClipboardContents::Range(rows)); } None => { - self.state.clipboard = Some(ClipboardContents::Cell( - self.book.get_current_cell_rendered()?, - )); - } - } - self.exit_range_select_mode()?; - Ok(()) - } - - fn copy_range_contents(&mut self) -> Result<(), anyhow::Error> { - self.update_range_selection()?; - match &self.state.range_select.get_range() { - Some(( - Address { - row: row_start, - col: col_start, - }, - Address { - row: row_end, - col: col_end, - }, - )) => { - let mut rows = Vec::new(); - for ri in (*row_start)..=(*row_end) { - let mut cols = Vec::new(); - for ci in (*col_start)..=(*col_end) { - cols.push( - self.book - .get_cell_addr_contents(&Address { row: ri, col: ci })?, - ); - } - rows.push(cols); - } - self.state.clipboard = Some(ClipboardContents::Range(rows)); - } - None => { - self.state.clipboard = Some(ClipboardContents::Cell( - self.book.get_current_cell_contents()?, - )); + self.state.clipboard = Some(ClipboardContents::Cell(if formatted { + self.book + .get_current_cell_rendered()? + } else { + self.book + .get_current_cell_contents()? + })); } } self.exit_range_select_mode()?; @@ -698,6 +669,11 @@ impl<'ws> Workspace<'ws> { self.book.get_current_cell_contents()?, )); } + KeyCode::Char('Y') => { + self.state.clipboard = Some(ClipboardContents::Cell( + self.book.get_current_cell_rendered()?, + )); + } KeyCode::Char('C') if key .modifiers diff --git a/src/ui/render/mod.rs b/src/ui/render/mod.rs index bedf8e6..2655307 100644 --- a/src/ui/render/mod.rs +++ b/src/ui/render/mod.rs @@ -28,25 +28,40 @@ impl<'ws> Workspace<'ws> { ]; let mut rs: Vec> = vec![ Box::new(|rect: Rect, buf: &mut Buffer, ws: &mut Self| { - let tabs = Tabs::new(ws.book.get_sheet_names().iter().enumerate().map(|(idx, name)| format!("{} {}", name, idx)).collect::>()) - .select(Some(ws.book.current_sheet as usize)); + let tabs = Tabs::new( + ws.book + .get_sheet_names() + .iter() + .enumerate() + .map(|(idx, name)| format!("{} {}", name, idx)) + .collect::>(), + ) + .select(Some(ws.book.current_sheet as usize)); tabs.render(rect, buf); }), Box::new(|rect: Rect, buf: &mut Buffer, ws: &mut Self| { - let [text_rect, info_rect] = Layout::horizontal(vec![Constraint::Fill(1),Constraint::Fill(1)]).areas(rect); + let [text_rect, info_rect] = + Layout::horizontal(vec![Constraint::Fill(1), Constraint::Fill(1)]).areas(rect); ws.text_area.render(text_rect, buf); let hint = Paragraph::new(vec![ Line::from(""), - Line::from("ALT-h to toggle help dialog").centered() + Line::from("ALT-h to toggle help dialog").centered(), ]); hint.render(info_rect, buf); }), Box::new(move |rect: Rect, buf: &mut Buffer, ws: &mut Self| { let sheet_name = ws.book.get_sheet_name().unwrap_or("Unknown"); let table_block = Block::bordered().title_top(sheet_name); - let viewport = Viewport::new(&ws.book, &ws.state.range_select) - .with_selected(ws.book.location.clone()) - .block(table_block); + let viewport = Viewport::new( + &ws.book, + if ws.state.modality() == &Modality::RangeSelect { + Some(&ws.state.range_select) + } else { + None + }, + ) + .with_selected(ws.book.location.clone()) + .block(table_block); StatefulWidget::render(viewport, rect, buf, &mut ws.state.viewport_state); }), ]; diff --git a/src/ui/render/test.rs b/src/ui/render/test.rs index 001e389..46c42cf 100644 --- a/src/ui/render/test.rs +++ b/src/ui/render/test.rs @@ -14,7 +14,7 @@ fn test_viewport_get_visible_columns() { let width = dbg!(dbg!(default_size) * 12 / 2); let app_state = AppState::default(); let viewport = - Viewport::new(&book, &app_state.range_select).with_selected(Address { row: 1, col: 17 }); + Viewport::new(&book, Some(&app_state.range_select)).with_selected(Address { row: 1, col: 17 }); let cols = viewport .get_visible_columns((width + 5) as u16, &mut state) .expect("Failed to get visible columns"); @@ -31,7 +31,7 @@ fn test_viewport_get_visible_rows() { let height = 6; let app_state = AppState::default(); let viewport = - Viewport::new(&book, &app_state.range_select).with_selected(Address { row: 17, col: 1 }); + Viewport::new(&book, Some(&app_state.range_select)).with_selected(Address { row: 17, col: 1 }); let rows = dbg!(viewport.get_visible_rows(height as u16, &mut state)); assert_eq!(height - 1, rows.len()); assert_eq!( @@ -51,7 +51,7 @@ fn test_viewport_visible_columns_after_length_change() { let width = dbg!(dbg!(default_size) * 12 / 2); { let app_state = AppState::default(); - let viewport = Viewport::new(&book, &app_state.range_select) + let viewport = Viewport::new(&book, Some(&app_state.range_select)) .with_selected(Address { row: 1, col: 17 }); let cols = viewport .get_visible_columns((width + 5) as u16, &mut state) @@ -65,7 +65,7 @@ fn test_viewport_visible_columns_after_length_change() { { let app_state = AppState::default(); let viewport = - Viewport::new(&book, &app_state.range_select).with_selected(Address { row: 1, col: 1 }); + Viewport::new(&book, Some(&app_state.range_select)).with_selected(Address { row: 1, col: 1 }); let cols = viewport .get_visible_columns((width + 5) as u16, &mut state) .expect("Failed to get visible columns"); diff --git a/src/ui/render/viewport.rs b/src/ui/render/viewport.rs index 1b33e9b..c91d975 100644 --- a/src/ui/render/viewport.rs +++ b/src/ui/render/viewport.rs @@ -37,7 +37,7 @@ pub struct ViewportState { pub struct Viewport<'ws> { pub(crate) selected: Address, book: &'ws Book, - range_selection: &'ws RangeSelection, + range_selection: Option<&'ws RangeSelection>, block: Option>, } @@ -47,7 +47,7 @@ pub(crate) const COLNAMES: [&'static str; 26] = [ ]; impl<'ws> Viewport<'ws> { - pub fn new(book: &'ws Book, app_state: &'ws RangeSelection) -> Self { + pub fn new(book: &'ws Book, app_state: Option<&'ws RangeSelection>) -> Self { Self { book, range_selection: app_state, @@ -160,7 +160,9 @@ impl<'ws> Viewport<'ws> { .get_cell_addr_rendered(&Address { row: ri, col: *ci }) .unwrap(); let mut cell = Cell::new(Text::raw(content)); - if let Some((start, end)) = &self.range_selection.get_range() { + if let Some((start, end)) = + &self.range_selection.map_or(None, |r| r.get_range()) + { if ri >= start.row && ri <= end.row && *ci >= start.col