Skip to content

Commit

Permalink
Move Rgb to cursive::style
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Jun 28, 2024
1 parent fc0f1df commit 48cafd5
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 158 deletions.
154 changes: 154 additions & 0 deletions cursive-core/src/style/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,160 @@ impl From<u8> for BaseColor {
}
}

/// RGB color.
///
/// If `T = u8` this is a 24-bit color.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Rgb<T = u8> {
/// Red component.
pub r: T,

/// Green component.
pub g: T,

/// Blue component.
pub b: T,
}

impl<T> From<[T; 3]> for Rgb<T> {
fn from(o: [T; 3]) -> Self {
let [r, g, b] = o;
Self { r, g, b }
}
}

impl From<u32> for Rgb<u8> {
fn from(hex: u32) -> Self {
Self::from_u32(hex)
}
}

impl From<Rgb<u8>> for Rgb<f32> {
fn from(o: Rgb<u8>) -> Self {
o.as_f32()
}
}

impl<T> Rgb<T> {
/// Create a new Rgb from individual r, g and b values.
pub fn new(r: T, g: T, b: T) -> Self {
Self { r, g, b }
}

/// Run a closure on each component pair.
pub fn zip_map<U, V>(a: Self, b: Rgb<U>, mut f: impl FnMut(T, U) -> V) -> Rgb<V> {
Self::zip(a, b).map(|(a, b)| f(a, b))
}

/// Zip two Rgb into a single Rgb of tuples.
pub fn zip<U>(a: Self, b: Rgb<U>) -> Rgb<(T, U)> {
Rgb {
r: (a.r, b.r),
g: (a.g, b.g),
b: (a.b, b.b),
}
}

/// Apply a closure on each component.
pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Rgb<U> {
Rgb {
r: f(self.r),
g: f(self.g),
b: f(self.b),
}
}
}

impl Rgb<f32> {
/// Casts each component to u8.
pub fn as_u8(self) -> Rgb<u8> {
self.map(|x| x as u8)
}

/// Convert to a Color.
pub fn as_color(self) -> Color {
self.as_u8().as_color()
}
}

impl Rgb<(f32, f32)> {
/// Interpolate each component individually.
pub fn interpolate(self, x: f32) -> Rgb<f32> {
self.map(|(a, b)| a * (1f32 - x) + b * x)
}
}

impl Rgb<(u8, u8)> {
/// Cast each component to a tuple of f32.
pub fn as_f32(self) -> Rgb<(f32, f32)> {
self.map(|(x, y)| (x as f32, y as f32))
}
}

impl Rgb<u8> {
/// Convert to a Color.
pub fn as_color(self) -> Color {
Color::Rgb(self.r, self.g, self.b)
}

/// Return a Rgb using the lowest 24 bits.
///
/// This can parse hex codes like `0xFF0000`.
pub const fn from_u32(hex: u32) -> Self {
let r = ((hex & 0xFF0000) >> 16) as u8;
let g = ((hex & 0x00FF00) >> 8) as u8;
let b = (hex & 0x0000FF) as u8;
Self { r, g, b }
}

/// Cast each component to f32.
pub fn as_f32(self) -> Rgb<f32> {
self.map(|x| x as f32)
}

/// Returns a pure red RGB color.
pub const fn red() -> Self {
Self::from_u32(0xFF0000)
}

/// Returns a pure green RGB color.
pub const fn green() -> Self {
Self::from_u32(0x00FF00)
}

/// Returns a pure blue RGB color.
pub const fn blue() -> Self {
Self::from_u32(0x0000FF)
}

/// Returns a pure yellow RGB color.
pub const fn yellow() -> Self {
Self::from_u32(0xFFFF00)
}
/// Returns a pure magenta RGB color.
pub const fn magenta() -> Self {
Self::from_u32(0xFF00FF)
}
/// Returns a pure cyan RGB color.
pub const fn cyan() -> Self {
Self::from_u32(0x00FFFF)
}
/// Returns a pure white RGB color.
pub const fn white() -> Self {
Self::from_u32(0xFFFFFF)
}
/// Returns a pure black RGB color.
pub const fn black() -> Self {
Self::from_u32(0x000000)
}
}

impl From<Rgb<u8>> for Color {
fn from(rgb: Rgb<u8>) -> Self {
rgb.as_color()
}
}

/// Represents a color used by the theme.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Color {
Expand Down
151 changes: 1 addition & 150 deletions cursive-core/src/style/gradient/mod.rs
Original file line number Diff line number Diff line change
@@ -1,154 +1,5 @@
//! Gradients
use crate::style::Color;
use crate::{Vec2, XY};

/// RGB color.
///
/// If `T = u8` this is a 24-bit color.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Rgb<T = u8> {
/// Red component.
pub r: T,

/// Green component.
pub g: T,

/// Blue component.
pub b: T,
}

impl<T> From<[T; 3]> for Rgb<T> {
fn from(o: [T; 3]) -> Self {
let [r, g, b] = o;
Self { r, g, b }
}
}

impl From<u32> for Rgb<u8> {
fn from(hex: u32) -> Self {
Self::from_u32(hex)
}
}

impl From<Rgb<u8>> for Rgb<f32> {
fn from(o: Rgb<u8>) -> Self {
o.as_f32()
}
}

impl<T> Rgb<T> {
/// Create a new Rgb from individual r, g and b values.
pub fn new(r: T, g: T, b: T) -> Self {
Self { r, g, b }
}

/// Run a closure on each component pair.
pub fn zip_map<U, V>(a: Self, b: Rgb<U>, mut f: impl FnMut(T, U) -> V) -> Rgb<V> {
Self::zip(a, b).map(|(a, b)| f(a, b))
}

/// Zip two Rgb into a single Rgb of tuples.
pub fn zip<U>(a: Self, b: Rgb<U>) -> Rgb<(T, U)> {
Rgb {
r: (a.r, b.r),
g: (a.g, b.g),
b: (a.b, b.b),
}
}

/// Apply a closure on each component.
pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Rgb<U> {
Rgb {
r: f(self.r),
g: f(self.g),
b: f(self.b),
}
}
}

impl Rgb<f32> {
/// Casts each component to u8.
pub fn as_u8(self) -> Rgb<u8> {
self.map(|x| x as u8)
}

/// Convert to a Color.
pub fn as_color(self) -> Color {
self.as_u8().as_color()
}
}

impl Rgb<(f32, f32)> {
/// Interpolate each component individually.
pub fn interpolate(self, x: f32) -> Rgb<f32> {
self.map(|(a, b)| a * (1f32 - x) + b * x)
}
}

impl Rgb<(u8, u8)> {
/// Cast each component to a tuple of f32.
pub fn as_f32(self) -> Rgb<(f32, f32)> {
self.map(|(x, y)| (x as f32, y as f32))
}
}

impl Rgb<u8> {
/// Convert to a Color.
pub fn as_color(self) -> Color {
Color::Rgb(self.r, self.g, self.b)
}

/// Return a Rgb using the lowest 24 bits.
///
/// This can parse hex codes like `0xFF0000`.
pub const fn from_u32(hex: u32) -> Self {
let r = ((hex & 0xFF0000) >> 16) as u8;
let g = ((hex & 0x00FF00) >> 8) as u8;
let b = (hex & 0x0000FF) as u8;
Self { r, g, b }
}

/// Cast each component to f32.
pub fn as_f32(self) -> Rgb<f32> {
self.map(|x| x as f32)
}

/// Returns a pure red RGB color.
pub const fn red() -> Self {
Self::from_u32(0xFF0000)
}

/// Returns a pure green RGB color.
pub const fn green() -> Self {
Self::from_u32(0x00FF00)
}

/// Returns a pure blue RGB color.
pub const fn blue() -> Self {
Self::from_u32(0x0000FF)
}

/// Returns a pure yellow RGB color.
pub const fn yellow() -> Self {
Self::from_u32(0xFFFF00)
}
/// Returns a pure magenta RGB color.
pub const fn magenta() -> Self {
Self::from_u32(0xFF00FF)
}
/// Returns a pure cyan RGB color.
pub const fn cyan() -> Self {
Self::from_u32(0x00FFFF)
}
/// Returns a pure white RGB color.
pub const fn white() -> Self {
Self::from_u32(0xFFFFFF)
}
/// Returns a pure black RGB color.
pub const fn black() -> Self {
Self::from_u32(0x000000)
}
}
use crate::{style::Rgb, Vec2, XY};

/// A linear gradient interpolating between 0 and 1.
pub struct Linear {
Expand Down
2 changes: 1 addition & 1 deletion cursive-core/src/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ mod palette;
mod style;

pub use self::border_style::BorderStyle;
pub use self::color::{BaseColor, Color};
pub use self::color::{BaseColor, Color, Rgb};
pub use self::color_pair::ColorPair;
pub use self::color_style::{ColorStyle, ColorType};
pub use self::effect::{ConcreteEffects, Effect, EffectStatus, Effects};
Expand Down
7 changes: 2 additions & 5 deletions cursive-core/src/utils/markup/gradient.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//! Generate StyledString with gradients.
use crate::style::{
gradient::{Linear, Rgb},
ColorStyle, Style,
};
use crate::style::{gradient::Linear, ColorStyle, Rgb, Style};
use crate::utils::markup::{StyledIndexedSpan, StyledString};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
Expand Down Expand Up @@ -95,7 +92,7 @@ where
#[cfg(test)]
mod tests {
use super::decorate_front;
use crate::style::gradient::Rgb;
use crate::style::Rgb;
use crate::utils::markup::cursup;

#[test]
Expand Down
7 changes: 5 additions & 2 deletions cursive/examples/gradient.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use cursive::event::EventResult;
use cursive::style::gradient::{Angled, Bilinear, Linear, Radial, Rgb};
use cursive::style::{
gradient::{Angled, Bilinear, Linear, Radial},
Rgb,
};
use cursive::traits::*;
use cursive::utils::markup::gradient;
use cursive::views::{Dialog, GradientView, OnEventView, TextView};
use cursive::{Cursive, XY};
use cursive::XY;

fn main() {
let mut siv = cursive::default();
Expand Down

0 comments on commit 48cafd5

Please sign in to comment.