lv-tui 0.1.1

A reactive TUI framework for Rust, inspired by Textual and React
Documentation
use crate::buffer::CellStyle;
use crate::geom::Insets;

/// 终端颜色
#[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 {
        match c {
            Color::Black => crossterm::style::Color::Black,
            Color::Red => crossterm::style::Color::DarkRed,
            Color::Green => crossterm::style::Color::DarkGreen,
            Color::Yellow => crossterm::style::Color::DarkYellow,
            Color::Blue => crossterm::style::Color::DarkBlue,
            Color::Magenta => crossterm::style::Color::DarkMagenta,
            Color::Cyan => crossterm::style::Color::DarkCyan,
            Color::White => crossterm::style::Color::Grey,
            Color::Gray => crossterm::style::Color::DarkGrey,
        }
    }
}

/// 长度规格
#[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 {
    /// 不换行,超出 clip 截断
    #[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 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,
            border: Border::None,
        }
    }
}

impl Style {
    // 视觉效果 builder
    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
    }

    // 布局 builder
    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 border(mut self, border: Border) -> Self {
        self.border = border;
        self
    }

    /// 转换为 CellStyle
    pub fn into_cell_style(&self) -> CellStyle {
        CellStyle {
            fg: self.fg,
            bg: self.bg,
            bold: self.bold,
            italic: self.italic,
            underline: self.underline,
        }
    }
}