1use gpui::Pixels;
2
3/// Calculates the child’s content-corner radius for a single nested level.
4///
5/// child_content_radius = max(0, parent_radius - parent_border - parent_padding + self_border)
6///
7/// - parent_radius: outer corner radius of the parent element
8/// - parent_border: border width of the parent element
9/// - parent_padding: padding of the parent element
10/// - self_border: border width of this child element (for content inset)
11pub fn inner_corner_radius(
12 parent_radius: Pixels,
13 parent_border: Pixels,
14 parent_padding: Pixels,
15 self_border: Pixels,
16) -> Pixels {
17 (parent_radius - parent_border - parent_padding + self_border).max(Pixels::ZERO)
18}
19
20/// Solver for arbitrarily deep nested corner radii.
21///
22/// Each nested level’s outer border-box radius is:
23/// R₀ = max(0, root_radius - root_border - root_padding)
24/// Rᵢ = max(0, Rᵢ₋₁ - childᵢ₋₁_border - childᵢ₋₁_padding) for i > 0
25pub struct CornerSolver {
26 root_radius: Pixels,
27 root_border: Pixels,
28 root_padding: Pixels,
29 children: Vec<(Pixels, Pixels)>, // (border, padding)
30}
31
32impl CornerSolver {
33 pub fn new(root_radius: Pixels, root_border: Pixels, root_padding: Pixels) -> Self {
34 Self {
35 root_radius,
36 root_border,
37 root_padding,
38 children: Vec::new(),
39 }
40 }
41
42 pub fn add_child(mut self, border: Pixels, padding: Pixels) -> Self {
43 self.children.push((border, padding));
44 self
45 }
46
47 pub fn corner_radius(&self, level: usize) -> Pixels {
48 if level == 0 {
49 return (self.root_radius - self.root_border - self.root_padding).max(Pixels::ZERO);
50 }
51 if level >= self.children.len() {
52 return Pixels::ZERO;
53 }
54 let mut r = (self.root_radius - self.root_border - self.root_padding).max(Pixels::ZERO);
55 for i in 0..level {
56 let (b, p) = self.children[i];
57 r = (r - b - p).max(Pixels::ZERO);
58 }
59 r
60 }
61}