From 1cc59e4e2f88e53563c228340192feadacb78d70 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Sat, 23 Nov 2024 21:14:53 -0500 Subject: [PATCH] wip: U/X columns * Take length from the col width value. Use a heuristic of 10 px per column length for now. Might make this configurable later? * Allow us to set the length. --- src/book/mod.rs | 24 ++++++++++++++++++++++++ src/book/test.rs | 9 +++++++++ src/ui/render.rs | 10 +++++----- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/book/mod.rs b/src/book/mod.rs index dfb91e6..37d9f70 100644 --- a/src/book/mod.rs +++ b/src/book/mod.rs @@ -16,6 +16,8 @@ use crate::ui::Address; #[cfg(test)] mod test; +const COL_PIXELS: f64 = 10.0; + /// A spreadsheet book with some internal state tracking. pub struct Book { pub(crate) model: Model, @@ -170,6 +172,20 @@ impl Book { Ok(self.get_sheet()?.dimension()) } + /// Get column size + pub fn get_col_size(&self, idx: usize) -> Result { + Ok((self + .get_sheet()? + .get_column_width(idx as i32) + .map_err(|e| anyhow!("Error getting column width: {:?}", e))? / COL_PIXELS) as usize) + } + + pub fn set_col_size(&mut self, idx: usize, cols: usize) -> Result<()> { + self.get_sheet_mut()?.set_column_width(idx as i32, cols as f64 * COL_PIXELS) + .map_err(|e| anyhow!("Error setting column width: {:?}", e))?; + Ok(()) + } + // Get the size of the current sheet as a `(row_count, column_count)` pub fn get_size(&self) -> Result<(usize, usize)> { let sheet = &self.get_sheet()?.sheet_data; @@ -227,6 +243,14 @@ impl Book { .worksheet(self.current_sheet) .map_err(|s| anyhow!("Invalid Worksheet: {}", s))?) } + + pub(crate) fn get_sheet_mut(&mut self) -> Result<&mut Worksheet> { + Ok(self + .model + .workbook + .worksheet_mut(self.current_sheet) + .map_err(|s| anyhow!("Invalid Worksheet: {}", s))?) + } } impl Default for Book { diff --git a/src/book/test.rs b/src/book/test.rs index 0055b8e..2f93449 100644 --- a/src/book/test.rs +++ b/src/book/test.rs @@ -89,3 +89,12 @@ fn test_book_insert_columns() { assert_eq!(Address {row: 2, col: 7, }, book.location); assert_eq!("1", book.get_current_cell_rendered().expect("Failed to get rendered content")); } + +#[test] +fn test_book_col_size() { + let mut book = Book::default(); + book.update_entry(&Address { row: 2, col: 2 }, "1") + .expect("failed to edit cell"); + book.set_col_size(1, 20).expect("Failed to set column size"); + assert_eq!(20, book.get_col_size(1).expect("Failed to get column size")); +} diff --git a/src/ui/render.rs b/src/ui/render.rs index 9062f34..658563b 100644 --- a/src/ui/render.rs +++ b/src/ui/render.rs @@ -60,7 +60,6 @@ impl<'t, 'book: 't> TryFrom<&'book Book> for Table<'t> { // TODO(zaphar): This is apparently expensive. Maybe we can cache it somehow? // We should do the correct thing here if this fails let (row_count, col_count) = value.get_size()?; - let sheet_name = value.get_sheet_name()?; let rows: Vec = (1..=row_count) .into_iter() .map(|ri| { @@ -90,20 +89,21 @@ impl<'t, 'book: 't> TryFrom<&'book Book> for Table<'t> { .collect(); let mut constraints: Vec = Vec::new(); constraints.push(Constraint::Max(5)); - for _ in 0..col_count { - constraints.push(Constraint::Min(5)); + for col_idx in 0..col_count { + let size = value.get_col_size(col_idx+1)?; + constraints.push(Constraint::Length(size as u16)); } let mut header = Vec::with_capacity(col_count as usize); + header.push(Cell::new("")); header.extend((0..(col_count as usize)).map(|i| { let count = (i / 26) + 1; Cell::new(COLNAMES[i % 26].repeat(count)) })); Ok(Table::new(rows, constraints) - .block(Block::bordered().title_top(sheet_name)) .header(Row::new(header).underlined()) .column_spacing(1) - .flex(Flex::SpaceAround)) + .flex(Flex::Start)) } type Error = anyhow::Error;