1use duat_core::ui::Axis;
2
3use super::{VarPoint, variables::Variables};
4use crate::area::Coord;
5
6mod combinations;
7
8pub use combinations::*;
9
10#[derive(Default, Clone, Copy, Debug)]
12pub enum Brush {
13 #[default]
15 Regular,
16 Thick,
18 Dashed,
20 ThickDashed,
22 Double,
24 Rounded,
26 Ascii,
28 Custom(char),
30}
31
32#[derive(Debug)]
34pub struct Edge {
35 lhs: VarPoint,
36 rhs: VarPoint,
37 axis: Axis,
38 fr: Frame,
39}
40
41impl Edge {
42 pub fn new(lhs: VarPoint, rhs: VarPoint, axis: Axis, fr: Frame) -> Self {
44 Self { lhs, rhs, axis, fr }
45 }
46
47 pub fn coords(&self, vars: &mut Variables) -> Option<EdgeCoords> {
49 let (lhs, _) = vars.coord(self.lhs, false);
50 let (rhs, _) = vars.coord(self.rhs, false);
51 if lhs.x == rhs.x || lhs.y == rhs.y {
52 return None;
53 }
54
55 let start = match self.axis {
56 Axis::Horizontal => Coord::new(rhs.x, lhs.y),
57 Axis::Vertical => Coord::new(lhs.x, rhs.y),
58 };
59 let end = match self.axis {
60 Axis::Horizontal => Coord::new(lhs.x, rhs.y),
61 Axis::Vertical => Coord::new(rhs.x, lhs.y),
62 };
63
64 Some(EdgeCoords::new(start, end, self.axis, self.fr.brush()))
65 }
66}
67
68#[derive(Clone, Copy)]
69pub struct EdgeCoords {
70 pub tl: Coord,
71 pub br: Coord,
72 pub axis: Axis,
73 pub line: Option<Brush>,
74}
75
76impl EdgeCoords {
77 fn new(tl: Coord, br: Coord, axis: Axis, line: Option<Brush>) -> Self {
78 Self { tl, br, axis, line }
79 }
80
81 pub fn crossing(&self, other: EdgeCoords) -> Option<(Coord, [Option<Brush>; 4])> {
82 if let Axis::Vertical = self.axis {
83 if let Axis::Vertical = other.axis {
84 if self.br.x == other.tl.x && self.br.y + 2 == other.tl.y {
85 let coord = Coord::new(self.br.x, self.br.y + 1);
86 return Some((coord, [None, self.line, None, other.line]));
87 } else {
88 return None;
89 }
90 } else {
91 return other.crossing(*self);
92 }
93 }
94
95 if let Axis::Horizontal = other.axis {
96 if self.br.y == other.br.y && self.br.x + 2 == other.tl.x {
97 let coord = Coord::new(self.br.x + 1, self.br.y);
98 Some((coord, [other.line, None, self.line, None]))
99 } else {
100 None
101 }
102 } else if self.tl.x <= other.tl.x + 1 && other.tl.x <= self.br.x + 1 {
103 let right_height = (other.tl.y..=other.br.y + 2).contains(&(self.br.y + 1));
104 let right = match right_height && other.br.x <= self.br.x {
105 true => self.line,
106 false => None,
107 };
108 let up = match other.tl.y <= self.tl.y && self.br.y <= other.br.y + 1 {
109 true => other.line,
110 false => None,
111 };
112 let left = match right_height && self.tl.x <= other.tl.x {
113 true => self.line,
114 false => None,
115 };
116 let down = match self.br.y <= other.br.y && other.tl.y <= self.tl.y + 1 {
117 true => other.line,
118 false => None,
119 };
120
121 if up.is_some() || down.is_some() {
122 let coord = Coord { x: other.tl.x, y: self.tl.y };
123
124 Some((coord, [right, up, left, down]))
125 } else {
126 None
127 }
128 } else {
129 None
130 }
131 }
132}
133
134#[derive(Clone, Copy, Debug)]
155pub enum Frame {
156 Empty,
158 Surround(Brush),
160 Border(Brush),
162 Vertical(Brush),
164 VerBorder(Brush),
166 Horizontal(Brush),
168 HorBorder(Brush),
170}
171
172impl Default for Frame {
173 fn default() -> Self {
174 Self::Border(Brush::Regular)
175 }
176}
177
178impl Frame {
179 pub(crate) fn files_edge_on(&self, axis: Axis) -> f64 {
183 let (hor_fr, ver_fr) = self.files_edges();
184 match axis {
185 Axis::Horizontal => hor_fr,
186 Axis::Vertical => ver_fr,
187 }
188 }
189
190 pub(crate) fn border_edge_on(&self, axis: Axis) -> f64 {
194 let (hor_fr, ver_fr) = self.border_edges();
195 match axis {
196 Axis::Horizontal => hor_fr,
197 Axis::Vertical => ver_fr,
198 }
199 }
200
201 fn brush(&self) -> Option<Brush> {
203 match self {
204 Self::Empty => None,
205 Self::Surround(brush)
206 | Self::Border(brush)
207 | Self::Vertical(brush)
208 | Self::VerBorder(brush)
209 | Self::Horizontal(brush)
210 | Self::HorBorder(brush) => Some(*brush),
211 }
212 }
213
214 fn files_edges(&self) -> (f64, f64) {
218 match self {
219 Self::Surround(_) => (1.0, 1.0),
220 Self::Vertical(_) => (1.0, 0.0),
221 Self::Horizontal(_) => (0.0, 1.0),
222 _ => (0.0, 0.0),
223 }
224 }
225
226 fn border_edges(&self) -> (f64, f64) {
230 match self {
231 Self::Surround(_) | Self::Border(_) => (1.0, 1.0),
232 Self::Vertical(_) | Self::VerBorder(_) => (1.0, 0.0),
233 Self::Horizontal(_) | Self::HorBorder(_) => (0.0, 1.0),
234 Self::Empty => (0.0, 0.0),
235 }
236 }
237}