wip: handle ranges and multiple columns or rows

This commit is contained in:
Jeremy Wall 2025-01-28 21:10:39 -05:00
parent b6b98bc099
commit aa0a1512f6
2 changed files with 103 additions and 64 deletions

View File

@ -465,35 +465,54 @@ impl<'ws> Workspace<'ws> {
Ok(Some(Cmd::Quit)) => {
Ok(Some(ExitCode::SUCCESS))
}
Ok(Some(Cmd::ColorRows(_count, _color))) => {
Ok(Some(Cmd::ColorRows(_count, color))) => {
let row_count = _count.unwrap_or(1);
let row = self.book.location.row;
let mut style = if let Some(style) = self.book.get_row_style(self.book.current_sheet, row)? {
for r in row..(row+row_count) {
let mut style = if let Some(style) = self.book.get_row_style(self.book.current_sheet, r)? {
style
} else {
self.book.create_style()
};
style.fill.bg_color = Some(_color.to_string());
self.book.set_row_style(&style, self.book.current_sheet, row)?;
style.fill.bg_color = Some(color.to_string());
self.book.set_row_style(&style, self.book.current_sheet, r)?;
}
Ok(None)
}
Ok(Some(Cmd::ColorColumns(_count, _color))) => {
Ok(Some(Cmd::ColorColumns(_count, color))) => {
let col_count = _count.unwrap_or(1);
let col = self.book.location.col;
let mut style = if let Some(style) = self.book.get_column_style(self.book.current_sheet, col)? {
for c in col..(col+col_count) {
let mut style = if let Some(style) = self.book.get_column_style(self.book.current_sheet, c)? {
style
} else {
self.book.create_style()
};
style.fill.bg_color = Some(_color.to_string());
self.book.set_col_style(&style, self.book.current_sheet, col)?;
style.fill.bg_color = Some(color.to_string());
self.book.set_col_style(&style, self.book.current_sheet, c)?;
}
Ok(None)
}
Ok(Some(Cmd::ColorCell(color))) => {
if let Some((start, end)) = self.state.range_select.get_range() {
for ri in start.row..=end.row {
for ci in start.col..=end.col {
let address = Address { row: ri, col: ci };
let sheet = self.book.current_sheet;
let mut style = self.book.get_cell_style(sheet, &address)
.expect("I think this should be impossible.").clone();
style.fill.bg_color = Some(color.to_string());
self.book.set_cell_style(&style, sheet, &address)?;
}
}
} else {
let address = self.book.location.clone();
let sheet = self.book.current_sheet;
let mut style = self.book.get_cell_style(sheet, &address)
.expect("I think this should be impossible.").clone();
style.fill.bg_color = Some(color.to_string());
self.book.set_cell_style(&style, sheet, &address)?;
}
Ok(None)
}
Ok(None) => {
@ -630,6 +649,9 @@ impl<'ws> Workspace<'ws> {
}
self.exit_range_select_mode()?;
}
KeyCode::Char(':') => {
self.enter_command_mode();
}
_ => {
// moop
}

View File

@ -192,18 +192,25 @@ impl<'ws> Viewport<'ws> {
.flex(Flex::Start))
}
fn compute_cell_style<'widget>(&self, ri: usize, ci: usize, mut cell: Cell<'widget>) -> Cell<'widget> {
let style = self.book.get_cell_style(self.book.current_sheet, &Address { row: ri, col: ci, });
let bg_color = map_color(style.as_ref().map(|s| s.fill.bg_color.as_ref()).flatten(), Color::Rgb(35, 33, 54));
let fg_color = map_color(style.as_ref().map(|s| s.fill.fg_color.as_ref()).flatten(), Color::White);
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
&& ci <= end.col
{
fn compute_cell_style<'widget>(
&self,
ri: usize,
ci: usize,
mut cell: Cell<'widget>,
) -> Cell<'widget> {
let style = self
.book
.get_cell_style(self.book.current_sheet, &Address { row: ri, col: ci });
let bg_color = map_color(
style.as_ref().map(|s| s.fill.bg_color.as_ref()).flatten(),
Color::Rgb(35, 33, 54),
);
let fg_color = map_color(
style.as_ref().map(|s| s.fill.fg_color.as_ref()).flatten(),
Color::White,
);
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 && ci <= end.col {
// This is a selected range
cell = cell.fg(Color::Black).bg(Color::LightBlue)
}
@ -220,7 +227,8 @@ impl<'ws> Viewport<'ws> {
}
pub(crate) fn map_color(color: Option<&String>, otherwise: Color) -> Color {
color.map(|s| match s.to_lowercase().as_str() {
color
.map(|s| match s.to_lowercase().as_str() {
"red" => Color::Red,
"blue" => Color::Blue,
"green" => Color::Green,
@ -249,11 +257,20 @@ pub(crate) fn map_color(color: Option<&String>, otherwise: Color) -> Color {
} else {
otherwise
}
} else if candidate.starts_with("rgb(") {
if let Ok(rgb) = <colorsys::Rgb as std::str::FromStr>::from_str(candidate) {
// Note that the colorsys rgb model clamps the f64 values to no more
// than 255.0 so the below casts are safe.
Color::Rgb(rgb.red() as u8, rgb.green() as u8, rgb.blue() as u8)
} else {
otherwise
}
} else {
otherwise
}
}
}).unwrap_or(otherwise)
})
.unwrap_or(otherwise)
}
impl<'ws> StatefulWidget for Viewport<'ws> {