use crate::buffer::CellStyle;
use crate::geom::Insets;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Theme {
Dark,
Light,
}
thread_local! {
pub static CURRENT_THEME: std::cell::RefCell<Theme> = std::cell::RefCell::new(Theme::Dark);
}
pub fn set_theme(theme: Theme) {
CURRENT_THEME.with(|t| *t.borrow_mut() = theme);
crate::runtime::FORCE_FULL_PAINT.with(|f| *f.borrow_mut() = true);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Color {
Black,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
Gray,
}
impl From<Color> for crossterm::style::Color {
fn from(c: Color) -> Self {
let dark = CURRENT_THEME.with(|t| *t.borrow() == Theme::Dark);
match (c, dark) {
(Color::Black, _) => crossterm::style::Color::Black,
(Color::Red, true) => crossterm::style::Color::DarkRed,
(Color::Red, false) => crossterm::style::Color::Red,
(Color::Green, true) => crossterm::style::Color::DarkGreen,
(Color::Green, false) => crossterm::style::Color::Green,
(Color::Yellow, true) => crossterm::style::Color::DarkYellow,
(Color::Yellow, false) => crossterm::style::Color::Yellow,
(Color::Blue, true) => crossterm::style::Color::DarkBlue,
(Color::Blue, false) => crossterm::style::Color::Blue,
(Color::Magenta, true) => crossterm::style::Color::DarkMagenta,
(Color::Magenta, false) => crossterm::style::Color::Magenta,
(Color::Cyan, true) => crossterm::style::Color::DarkCyan,
(Color::Cyan, false) => crossterm::style::Color::Cyan,
(Color::White, _) => crossterm::style::Color::Grey,
(Color::Gray, true) => crossterm::style::Color::DarkGrey,
(Color::Gray, false) => crossterm::style::Color::Grey,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Length {
Auto,
Fixed(u16),
Percent(u16),
Fraction(u16),
}
impl Default for Length {
fn default() -> Self {
Length::Auto
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Layout {
None,
Vertical,
Horizontal,
}
impl Default for Layout {
fn default() -> Self {
Layout::None
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TextWrap {
#[default]
None,
Char,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TextAlign {
#[default]
Left,
Center,
Right,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum TextTruncate {
#[default]
None,
Ellipsis,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Border {
#[default]
None,
Plain,
Rounded,
Double,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Style {
pub fg: Option<Color>,
pub bg: Option<Color>,
pub bold: bool,
pub italic: bool,
pub underline: bool,
pub width: Length,
pub height: Length,
pub padding: Insets,
pub margin: Insets,
pub layout: Layout,
pub gap: u16,
pub flex_grow: u16,
pub flex_shrink: bool,
pub border: Border,
}
impl Default for Style {
fn default() -> Self {
Self {
fg: None,
bg: None,
bold: false,
italic: false,
underline: false,
width: Length::Auto,
height: Length::Auto,
padding: Insets::ZERO,
margin: Insets::ZERO,
layout: Layout::None,
gap: 0,
flex_grow: 0,
flex_shrink: true,
border: Border::None,
}
}
}
impl Style {
pub fn fg(mut self, color: Color) -> Self {
self.fg = Some(color);
self
}
pub fn bg(mut self, color: Color) -> Self {
self.bg = Some(color);
self
}
pub fn bold(mut self) -> Self {
self.bold = true;
self
}
pub fn italic(mut self) -> Self {
self.italic = true;
self
}
pub fn underline(mut self) -> Self {
self.underline = true;
self
}
pub fn width(mut self, width: Length) -> Self {
self.width = width;
self
}
pub fn height(mut self, height: Length) -> Self {
self.height = height;
self
}
pub fn padding(mut self, value: u16) -> Self {
self.padding = Insets::all(value);
self
}
pub fn margin(mut self, value: u16) -> Self {
self.margin = Insets::all(value);
self
}
pub fn layout(mut self, layout: Layout) -> Self {
self.layout = layout;
self
}
pub fn gap(mut self, gap: u16) -> Self {
self.gap = gap;
self
}
pub fn flex_grow(mut self, grow: u16) -> Self {
self.flex_grow = grow;
self
}
pub fn flex_shrink(mut self, shrink: bool) -> Self {
self.flex_shrink = shrink;
self
}
pub fn border(mut self, border: Border) -> Self {
self.border = border;
self
}
pub fn into_cell_style(&self) -> CellStyle {
CellStyle {
fg: self.fg,
bg: self.bg,
bold: self.bold,
italic: self.italic,
underline: self.underline,
}
}
}