1use crossterm::style::{Attribute, Color as CtColor, ContentStyle};
4use emux_term::Color;
5use emux_term::grid::{Cell, UnderlineStyle};
6
7pub fn color_to_crossterm(color: &Color) -> CtColor {
9 match color {
10 Color::Default => CtColor::Reset,
11 Color::Indexed(idx) => CtColor::AnsiValue(*idx),
12 Color::Rgb(r, g, b) => CtColor::Rgb {
13 r: *r,
14 g: *g,
15 b: *b,
16 },
17 }
18}
19
20pub fn cell_style(cell: &Cell) -> ContentStyle {
22 let mut style = ContentStyle::new();
23 style.foreground_color = Some(color_to_crossterm(&cell.fg));
24 style.background_color = Some(color_to_crossterm(&cell.bg));
25
26 if cell.attrs.bold {
27 style.attributes.set(Attribute::Bold);
28 }
29 if cell.attrs.italic {
30 style.attributes.set(Attribute::Italic);
31 }
32 match cell.attrs.underline {
33 UnderlineStyle::None => {}
34 UnderlineStyle::Single => {
35 style.attributes.set(Attribute::Underlined);
36 }
37 UnderlineStyle::Double => {
38 style.attributes.set(Attribute::DoubleUnderlined);
39 }
40 UnderlineStyle::Curly => {
41 style.attributes.set(Attribute::Undercurled);
42 }
43 }
44 if cell.attrs.blink {
45 style.attributes.set(Attribute::SlowBlink);
46 }
47 if cell.attrs.reverse {
48 style.attributes.set(Attribute::Reverse);
49 }
50 if cell.attrs.invisible {
51 style.attributes.set(Attribute::Hidden);
52 }
53 if cell.attrs.strikethrough {
54 style.attributes.set(Attribute::CrossedOut);
55 }
56
57 style
58}
59
60pub fn render_row(cells: &[Cell], width: usize) -> Vec<(ContentStyle, String)> {
66 let mut spans: Vec<(ContentStyle, String)> = Vec::new();
67 let mut col = 0;
68
69 for cell in cells.iter().take(width) {
70 if cell.width == 0 {
72 col += 1;
73 continue;
74 }
75
76 let style = cell_style(cell);
77 let ch = if cell.c < ' ' { ' ' } else { cell.c };
78
79 if let Some(last) = spans.last_mut() {
80 if last.0 == style {
81 last.1.push(ch);
82 } else {
83 spans.push((style, ch.to_string()));
84 }
85 } else {
86 spans.push((style, ch.to_string()));
87 }
88
89 col += cell.width as usize;
90 }
91
92 while col < width {
94 let style = ContentStyle::new();
95 if let Some(last) = spans.last_mut() {
96 if last.0 == style {
97 last.1.push(' ');
98 } else {
99 spans.push((style, " ".to_string()));
100 }
101 } else {
102 spans.push((style, " ".to_string()));
103 }
104 col += 1;
105 }
106
107 spans
108}