thedes_tui/text/
style.rs

1use thedes_tui_core::{
2    color::ColorPair,
3    geometry::{Coord, CoordPair},
4    mutation::{Mutation, Set},
5};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct Style<C = Set<ColorPair>>
9where
10    C: Mutation<ColorPair>,
11{
12    left_margin: Coord,
13    right_margin: Coord,
14    top_margin: Coord,
15    bottom_margin: Coord,
16    min_width: Coord,
17    max_width: Coord,
18    min_height: Coord,
19    max_height: Coord,
20    align_numer: Coord,
21    align_denom: Coord,
22    colors: C,
23}
24
25impl Default for Style {
26    fn default() -> Self {
27        Self::new_with_colors(Set::default())
28    }
29}
30
31impl<C> Style<C>
32where
33    C: Mutation<ColorPair>,
34{
35    pub fn new_with_colors(colors: C) -> Self {
36        Self {
37            left_margin: 0,
38            right_margin: 0,
39            top_margin: 0,
40            bottom_margin: 0,
41            min_width: 0,
42            max_width: Coord::max_value(),
43            min_height: 0,
44            max_height: Coord::max_value(),
45            align_numer: 0,
46            align_denom: 1,
47            colors,
48        }
49    }
50
51    pub fn map_colors<F, D>(self, mapper: F) -> Style<D>
52    where
53        F: FnOnce(C) -> D,
54        D: Mutation<ColorPair>,
55    {
56        Style {
57            left_margin: self.left_margin,
58            right_margin: self.right_margin,
59            top_margin: self.top_margin,
60            bottom_margin: self.bottom_margin,
61            min_width: self.min_width,
62            max_width: self.max_width,
63            min_height: self.min_height,
64            max_height: self.max_height,
65            align_numer: self.align_numer,
66            align_denom: self.align_denom,
67            colors: mapper(self.colors),
68        }
69    }
70
71    pub fn with_colors<D>(self, colors: D) -> Style<D>
72    where
73        D: Mutation<ColorPair>,
74    {
75        self.map_colors(|_| colors)
76    }
77
78    pub fn with_left_margin(self, left_margin: Coord) -> Self {
79        Self { left_margin, ..self }
80    }
81
82    pub fn with_right_margin(self, right_margin: Coord) -> Self {
83        Self { right_margin, ..self }
84    }
85
86    pub fn with_top_margin(self, top_margin: Coord) -> Self {
87        Self { top_margin, ..self }
88    }
89
90    pub fn with_bottom_margin(self, bottom_margin: Coord) -> Self {
91        Self { bottom_margin, ..self }
92    }
93
94    pub fn with_min_width(self, min_width: Coord) -> Self {
95        Self { min_width, ..self }
96    }
97
98    pub fn with_max_width(self, max_width: Coord) -> Self {
99        Self { max_width, ..self }
100    }
101
102    pub fn with_min_height(self, min_height: Coord) -> Self {
103        Self { min_height, ..self }
104    }
105
106    pub fn with_max_height(self, max_height: Coord) -> Self {
107        Self { max_height, ..self }
108    }
109
110    pub fn with_align(self, align_numer: Coord, align_denom: Coord) -> Self {
111        Self { align_numer, align_denom, ..self }
112    }
113
114    pub fn left_margin(&self) -> Coord {
115        self.left_margin
116    }
117
118    pub fn right_margin(&self) -> Coord {
119        self.right_margin
120    }
121
122    pub fn top_margin(&self) -> Coord {
123        self.top_margin
124    }
125
126    pub fn bottom_margin(&self) -> Coord {
127        self.bottom_margin
128    }
129
130    pub fn min_width(&self) -> Coord {
131        self.min_width
132    }
133
134    pub fn max_width(&self) -> Coord {
135        self.max_width
136    }
137
138    pub fn min_height(&self) -> Coord {
139        self.min_height
140    }
141
142    pub fn max_height(&self) -> Coord {
143        self.max_height
144    }
145
146    pub fn align_numer(&self) -> Coord {
147        self.align_numer
148    }
149
150    pub fn align_denom(&self) -> Coord {
151        self.align_denom
152    }
153
154    pub fn colors(&self) -> &C {
155        &self.colors
156    }
157
158    pub fn make_margin_below(&self) -> CoordPair {
159        CoordPair { x: self.left_margin, y: self.top_margin }
160    }
161
162    pub fn make_margin_above(&self) -> CoordPair {
163        CoordPair { x: self.right_margin, y: self.bottom_margin }
164    }
165
166    pub fn make_min_size(&self) -> CoordPair {
167        CoordPair { x: self.min_width, y: self.min_height }
168    }
169
170    pub fn make_max_size(&self) -> CoordPair {
171        CoordPair { x: self.max_width, y: self.max_height }
172    }
173
174    pub fn make_size(&self, canvas_size: CoordPair) -> CoordPair {
175        CoordPair {
176            y: canvas_size
177                .y
178                .saturating_sub(self.make_margin_below().y)
179                .saturating_sub(self.make_margin_above().y)
180                .min(self.make_max_size().y),
181            x: canvas_size
182                .x
183                .saturating_sub(self.make_margin_below().x)
184                .saturating_sub(self.make_margin_above().x)
185                .min(self.make_max_size().x),
186        }
187    }
188}