diff --git a/src/ui/mod.rs b/src/ui/mod.rs index a6b46b0..ac85fc7 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -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)? { - 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)?; + 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, 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)? { - 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)?; + 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, c)?; + } Ok(None) } Ok(Some(Cmd::ColorCell(color))) => { - 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)?; + 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 } diff --git a/src/ui/render/viewport.rs b/src/ui/render/viewport.rs index 06b6176..e37e8f8 100644 --- a/src/ui/render/viewport.rs +++ b/src/ui/render/viewport.rs @@ -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,40 +227,50 @@ impl<'ws> Viewport<'ws> { } pub(crate) fn map_color(color: Option<&String>, otherwise: Color) -> Color { - color.map(|s| match s.to_lowercase().as_str() { - "red" => Color::Red, - "blue" => Color::Blue, - "green" => Color::Green, - "magenta" => Color::Magenta, - "cyan" => Color::Cyan, - "white" => Color::White, - "yellow" => Color::Yellow, - "black" => Color::Black, - "gray" | "grey" => Color::Gray, - "lightred" => Color::LightRed, - "lightblue" => Color::LightBlue, - "lightgreen" => Color::LightGreen, - "lightmagenta" => Color::LightMagenta, - "lightcyan" => Color::LightCyan, - "lightyellow" => Color::LightYellow, - "darkgrey" | "darkgray" => Color::DarkGray, - candidate => { - // TODO(jeremy): Should we support more syntaxes than hex string? - // hsl(...) ?? - // rgb(...) ?? - if candidate.starts_with("#") { - if let Ok(rgb) = colorsys::Rgb::from_hex_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) + color + .map(|s| match s.to_lowercase().as_str() { + "red" => Color::Red, + "blue" => Color::Blue, + "green" => Color::Green, + "magenta" => Color::Magenta, + "cyan" => Color::Cyan, + "white" => Color::White, + "yellow" => Color::Yellow, + "black" => Color::Black, + "gray" | "grey" => Color::Gray, + "lightred" => Color::LightRed, + "lightblue" => Color::LightBlue, + "lightgreen" => Color::LightGreen, + "lightmagenta" => Color::LightMagenta, + "lightcyan" => Color::LightCyan, + "lightyellow" => Color::LightYellow, + "darkgrey" | "darkgray" => Color::DarkGray, + candidate => { + // TODO(jeremy): Should we support more syntaxes than hex string? + // hsl(...) ?? + // rgb(...) ?? + if candidate.starts_with("#") { + if let Ok(rgb) = colorsys::Rgb::from_hex_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 if candidate.starts_with("rgb(") { + if let Ok(rgb) = ::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 } - } else { - otherwise } - } - }).unwrap_or(otherwise) + }) + .unwrap_or(otherwise) } impl<'ws> StatefulWidget for Viewport<'ws> {