Skip to content

Commit

Permalink
feat(style): add conversions from the palette crate colors (#1172)
Browse files Browse the repository at this point in the history
This is behind the "palette" feature flag.

```rust
use palette::{LinSrgb, Srgb};
use ratatui::style::Color;

let color = Color::from(Srgb::new(1.0f32, 0.0, 0.0));
let color = Color::from(LinSrgb::new(1.0f32, 0.0, 0.0));
```
  • Loading branch information
joshka authored Jun 8, 2024
1 parent e6871b9 commit 10d7788
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 13 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ document-features = { version = "0.2.7", optional = true }
itertools = "0.13"
lru = "0.12.0"
paste = "1.0.2"
palette = { version = "0.7.6", optional = true }
serde = { version = "1", optional = true, features = ["derive"] }
stability = "0.2.0"
strum = { version = "0.26", features = ["derive"] }
Expand Down Expand Up @@ -122,6 +123,9 @@ serde = ["dep:serde", "bitflags/serde", "compact_str/serde"]
## enables the [`border!`] macro.
macros = []

## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color).
palette = ["dep:palette"]

## enables all widgets.
all-widgets = ["widget-calendar"]

Expand Down
13 changes: 5 additions & 8 deletions src/layout/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1881,14 +1881,11 @@ mod tests {

let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Percentage(10),
Constraint::Max(5),
Constraint::Min(1),
]
.as_ref(),
)
.constraints([
Constraint::Percentage(10),
Constraint::Max(5),
Constraint::Min(1),
])
.split(target);

assert_eq!(target.height, chunks.iter().map(|r| r.height).sum::<u16>());
Expand Down
9 changes: 5 additions & 4 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,14 @@
use std::fmt;

use bitflags::bitflags;

mod color;
mod stylize;

pub use color::{Color, ParseColorError};
pub use stylize::{Styled, Stylize};

mod color;
pub mod palette;
#[cfg(feature = "palette")]
mod palette_conversion;
mod stylize;

bitflags! {
/// Modifier changes the way a piece of text is displayed.
Expand Down
83 changes: 83 additions & 0 deletions src/style/palette_conversion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Conversions from colors in the `palette` crate to [`Color`].

use ::palette::{
bool_mask::LazySelect,
num::{Arithmetics, MulSub, PartialCmp, Powf, Real},
LinSrgb,
};
use palette::{stimulus::IntoStimulus, Srgb};

use super::Color;

/// Convert an [`palette::Srgb`] color to a [`Color`].
///
/// # Examples
///
/// ```
/// use palette::Srgb;
/// use ratatui::style::Color;
///
/// let color = Color::from(Srgb::new(1.0f32, 0.0, 0.0));
/// assert_eq!(color, Color::Rgb(255, 0, 0));
/// ```
impl<T: IntoStimulus<u8>> From<Srgb<T>> for Color {
fn from(color: Srgb<T>) -> Self {
let (red, green, blue) = color.into_format().into_components();
Color::Rgb(red, green, blue)
}
}

/// Convert a [`palette::LinSrgb`] color to a [`Color`].
///
/// Note: this conversion only works for floating point linear sRGB colors. If you have a linear
/// sRGB color in another format, you need to convert it to floating point first.
///
/// # Examples
///
/// ```
/// use palette::LinSrgb;
/// use ratatui::style::Color;
///
/// let color = Color::from(LinSrgb::new(1.0f32, 0.0, 0.0));
/// assert_eq!(color, Color::Rgb(255, 0, 0));
/// ```
impl<T: IntoStimulus<u8>> From<LinSrgb<T>> for Color
where
T: Real + Powf + MulSub + Arithmetics + PartialCmp + Clone,
T::Mask: LazySelect<T>,
{
fn from(color: LinSrgb<T>) -> Self {
let srgb_color = Srgb::<T>::from_linear(color);
Color::from(srgb_color)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn from_srgb() {
const RED: Color = Color::Rgb(255, 0, 0);
assert_eq!(Color::from(Srgb::new(255u8, 0, 0)), RED);
assert_eq!(Color::from(Srgb::new(65535u16, 0, 0)), RED);
assert_eq!(Color::from(Srgb::new(1.0f32, 0.0, 0.0)), RED);

assert_eq!(
Color::from(Srgb::new(0.5f32, 0.5, 0.5)),
Color::Rgb(128, 128, 128)
);
}

#[test]
fn from_lin_srgb() {
const RED: Color = Color::Rgb(255, 0, 0);
assert_eq!(Color::from(LinSrgb::new(1.0f32, 0.0, 0.0)), RED);
assert_eq!(Color::from(LinSrgb::new(1.0f64, 0.0, 0.0)), RED);

assert_eq!(
Color::from(LinSrgb::new(0.5f32, 0.5, 0.5)),
Color::Rgb(188, 188, 188)
);
}
}
3 changes: 2 additions & 1 deletion src/widgets/barchart/bar_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ impl<'a> From<&[(&'a str, u64)]> for BarGroup<'a> {

impl<'a, const N: usize> From<&[(&'a str, u64); N]> for BarGroup<'a> {
fn from(value: &[(&'a str, u64); N]) -> Self {
Self::from(value.as_ref())
let value: &[(&'a str, u64)] = value.as_ref();
Self::from(value)
}
}

Expand Down

0 comments on commit 10d7788

Please sign in to comment.