frozen_term/terminal/
style.rs1use std::{cell::LazyCell, sync::Arc};
2
3use termwiz::color::ColorAttribute;
4use wezterm_term::color::ColorPalette;
5
6use iced::{Padding, Pixels};
7
8#[derive(Clone)]
9pub struct Style {
10 pub line_height: iced::widget::text::LineHeight,
11 pub text_size: Option<Pixels>,
12 pub padding: iced::Padding,
13 pub background_color: iced::Color,
14 pub foreground_color: iced::Color,
15 pub font: iced::Font,
16 pub cursor_shape: CursorShape,
17 pub palette: Arc<Palette256>,
21}
22
23pub struct Palette256(pub [iced::Color; 256]);
24
25#[derive(Debug, Clone, Copy)]
26pub enum CursorShape {
27 Block,
28 Underline,
29 Bar,
30}
31
32impl Palette256 {
33 fn from_wezterm(palette: wezterm_term::color::Palette256) -> Self {
34 let mut iced_palette = [iced::Color::BLACK; 256];
35
36 for (wez_color, iced_color) in palette.0.into_iter().zip(iced_palette.iter_mut()) {
37 let (r, g, b, a) = wez_color.to_tuple_rgba();
38 *iced_color = iced::Color::from_rgba(r, g, b, a);
39 }
40
41 Self(iced_palette)
42 }
43}
44
45const DEFAULT_STYLE: LazyCell<Style> = LazyCell::new(|| {
46 let palette = ColorPalette::default();
47
48 let (r, g, b, a) = palette.background.to_tuple_rgba();
49 let background_color = iced::Color::from_rgba(r, g, b, a);
50
51 let (r, g, b, a) = palette.foreground.to_tuple_rgba();
52 let foreground_color = iced::Color::from_rgba(r, g, b, a);
53
54 Style {
55 line_height: iced::widget::text::LineHeight::default(),
56 text_size: None,
57 padding: Padding::new(10.0),
58 cursor_shape: CursorShape::Underline,
59 background_color,
60 foreground_color,
61 font: iced::Font::MONOSPACE,
62 palette: Arc::new(Palette256::from_wezterm(palette.colors)),
64 }
65});
66
67impl Default for Style {
68 fn default() -> Self {
69 DEFAULT_STYLE.clone()
70 }
71}
72
73impl Style {
74 pub fn line_height(mut self, line_height: impl Into<iced::widget::text::LineHeight>) -> Self {
75 self.line_height = line_height.into();
76 self
77 }
78
79 pub fn text_size(mut self, size: impl Into<Pixels>) -> Self {
80 self.text_size = Some(size.into());
81 self
82 }
83
84 pub fn padding(mut self, padding: Padding) -> Self {
85 self.padding = padding;
86 self
87 }
88
89 pub fn foreground_color(mut self, color: impl Into<iced::Color>) -> Self {
90 self.foreground_color = color.into();
91 self
92 }
93
94 pub fn background_color(mut self, color: impl Into<iced::Color>) -> Self {
95 self.background_color = color.into();
96 self
97 }
98
99 pub fn font(mut self, font: iced::Font) -> Self {
100 self.font = font;
101 self
102 }
103
104 pub fn palette(mut self, palette: Arc<Palette256>) -> Self {
105 self.palette = palette;
106 self
107 }
108
109 pub fn cursor_shape(mut self, shape: CursorShape) -> Self {
110 self.cursor_shape = shape;
111 self
112 }
113
114 pub(crate) fn get_color(&self, color: ColorAttribute) -> Option<iced::Color> {
115 match color {
116 ColorAttribute::TrueColorWithPaletteFallback(srgba_tuple, _)
117 | ColorAttribute::TrueColorWithDefaultFallback(srgba_tuple) => {
118 let (r, g, b, a) = srgba_tuple.to_tuple_rgba();
119 Some(iced::Color::from_rgba(r, g, b, a))
120 }
121 ColorAttribute::PaletteIndex(index) => Some(self.palette.0[index as usize]),
122 ColorAttribute::Default => None,
123 }
124 }
125}