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}