tabled/settings/shadow/
mod.rs1use crate::{
31 grid::ansi::ANSIBuf,
32 grid::config::{ColoredConfig, Indent, Offset, Sides},
33 settings::{color::Color, TableOption},
34};
35
36#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
42pub struct Shadow {
43 c: char,
44 size: usize,
45 size_offset: usize,
46 direction: Sides<bool>,
47 color: Option<Color>,
48}
49
50impl Shadow {
51 pub const DEFAULT_FILL: char = '▒';
53
54 pub fn new(size: usize) -> Self {
59 Self {
60 c: Self::DEFAULT_FILL,
61 size,
62 size_offset: 1,
63 direction: Sides::new(false, true, false, true),
64 color: None,
65 }
66 }
67
68 pub fn set_fill(mut self, c: char) -> Self {
70 self.c = c;
71 self
72 }
73
74 pub fn set_offset(mut self, size: usize) -> Self {
76 self.size_offset = size;
77 self
78 }
79
80 pub fn set_top(mut self) -> Self {
82 self.direction.top = true;
83 self.direction.bottom = false;
84 self
85 }
86
87 pub fn set_bottom(mut self) -> Self {
89 self.direction.bottom = true;
90 self.direction.top = false;
91 self
92 }
93
94 pub fn set_left(mut self) -> Self {
96 self.direction.left = true;
97 self.direction.right = false;
98 self
99 }
100
101 pub fn set_right(mut self) -> Self {
103 self.direction.right = true;
104 self.direction.left = false;
105 self
106 }
107
108 pub fn set_color(mut self, color: Color) -> Self {
110 self.color = Some(color);
111 self
112 }
113}
114
115impl<R, D> TableOption<R, ColoredConfig, D> for Shadow {
116 fn change(self, _: &mut R, cfg: &mut ColoredConfig, _: &mut D) {
117 set_margin(cfg, self.size, self.c, &self.direction);
118 set_margin_offset(cfg, self.size_offset, &self.direction);
119
120 if let Some(color) = &self.color {
121 set_margin_color(cfg, color.clone().into(), &self.direction);
122 }
123 }
124}
125
126fn set_margin(cfg: &mut ColoredConfig, size: usize, c: char, direction: &Sides<bool>) {
127 let mut margin: Sides<Indent> = Sides::default();
128 if direction.top {
129 margin.top.size = size;
130 margin.top.fill = c;
131 }
132
133 if direction.bottom {
134 margin.bottom.size = size;
135 margin.bottom.fill = c;
136 }
137
138 if direction.left {
139 margin.left.size = size;
140 margin.left.fill = c;
141 }
142
143 if direction.right {
144 margin.right.size = size;
145 margin.right.fill = c;
146 }
147
148 cfg.set_margin(margin);
149}
150
151fn set_margin_offset(cfg: &mut ColoredConfig, size: usize, direction: &Sides<bool>) {
152 let mut margin = Sides::filled(Offset::Start(0));
153 if direction.right && direction.bottom {
154 margin.bottom = Offset::Start(size);
155 margin.right = Offset::Start(size);
156 }
157
158 if direction.right && direction.top {
159 margin.top = Offset::Start(size);
160 margin.right = Offset::End(size);
161 }
162
163 if direction.left && direction.bottom {
164 margin.bottom = Offset::End(size);
165 margin.left = Offset::Start(size);
166 }
167
168 if direction.left && direction.top {
169 margin.top = Offset::End(size);
170 margin.left = Offset::End(size);
171 }
172
173 cfg.set_margin_offset(margin);
174}
175
176fn set_margin_color(cfg: &mut ColoredConfig, color: ANSIBuf, direction: &Sides<bool>) {
177 let mut margin: Sides<Option<ANSIBuf>> = Sides::default();
178 if direction.right {
179 margin.right = Some(color.clone());
180 }
181
182 if direction.top {
183 margin.top = Some(color.clone());
184 }
185
186 if direction.left {
187 margin.left = Some(color.clone());
188 }
189
190 if direction.bottom {
191 margin.bottom = Some(color.clone());
192 }
193
194 cfg.set_margin_color(margin);
195}