Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T05:38:07.508Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

divider.rs

240 lines · 7.7 KB · rust
1use gpui::{Hsla, IntoElement, PathBuilder, Refineable as _, StyleRefinement, canvas, point};
2
3use crate::prelude::*;
4
5#[derive(Clone, Copy, PartialEq)]
6enum DividerStyle {
7    Solid,
8    Dashed,
9}
10
11#[derive(Clone, Copy, PartialEq)]
12enum DividerDirection {
13    Horizontal,
14    Vertical,
15}
16
17/// The color of a [`Divider`].
18#[derive(Default)]
19pub enum DividerColor {
20    Border,
21    BorderFaded,
22    #[default]
23    BorderVariant,
24}
25
26impl DividerColor {
27    pub fn hsla(self, cx: &mut App) -> Hsla {
28        match self {
29            DividerColor::Border => cx.theme().colors().border,
30            DividerColor::BorderFaded => cx.theme().colors().border.opacity(0.6),
31            DividerColor::BorderVariant => cx.theme().colors().border_variant,
32        }
33    }
34}
35
36#[derive(IntoElement, RegisterComponent)]
37pub struct Divider {
38    line_style: DividerStyle,
39    direction: DividerDirection,
40    color: DividerColor,
41    style: StyleRefinement,
42    inset: bool,
43}
44
45impl Divider {
46    pub fn horizontal() -> Self {
47        Self {
48            line_style: DividerStyle::Solid,
49            direction: DividerDirection::Horizontal,
50            color: DividerColor::default(),
51            style: StyleRefinement::default(),
52            inset: false,
53        }
54    }
55
56    pub fn vertical() -> Self {
57        Self {
58            line_style: DividerStyle::Solid,
59            direction: DividerDirection::Vertical,
60            color: DividerColor::default(),
61            style: StyleRefinement::default(),
62            inset: false,
63        }
64    }
65
66    pub fn horizontal_dashed() -> Self {
67        Self {
68            line_style: DividerStyle::Dashed,
69            direction: DividerDirection::Horizontal,
70            color: DividerColor::default(),
71            style: StyleRefinement::default(),
72            inset: false,
73        }
74    }
75
76    pub fn vertical_dashed() -> Self {
77        Self {
78            line_style: DividerStyle::Dashed,
79            direction: DividerDirection::Vertical,
80            color: DividerColor::default(),
81            style: StyleRefinement::default(),
82            inset: false,
83        }
84    }
85
86    pub fn inset(mut self) -> Self {
87        self.inset = true;
88        self
89    }
90
91    pub fn color(mut self, color: DividerColor) -> Self {
92        self.color = color;
93        self
94    }
95
96    pub fn render_solid(self, base: Div, cx: &mut App) -> impl IntoElement {
97        base.bg(self.color.hsla(cx))
98    }
99
100    pub fn render_dashed(self, base: Div) -> impl IntoElement {
101        base.relative().child(
102            canvas(
103                |_, _, _| {},
104                move |bounds, _, window, cx| {
105                    let mut builder = PathBuilder::stroke(px(1.)).dash_array(&[px(4.), px(2.)]);
106                    let (start, end) = match self.direction {
107                        DividerDirection::Horizontal => {
108                            let x = bounds.origin.x;
109                            let y = bounds.origin.y + px(0.5);
110                            (point(x, y), point(x + bounds.size.width, y))
111                        }
112                        DividerDirection::Vertical => {
113                            let x = bounds.origin.x + px(0.5);
114                            let y = bounds.origin.y;
115                            (point(x, y), point(x, y + bounds.size.height))
116                        }
117                    };
118                    builder.move_to(start);
119                    builder.line_to(end);
120                    if let Ok(line) = builder.build() {
121                        window.paint_path(line, self.color.hsla(cx));
122                    }
123                },
124            )
125            .absolute()
126            .size_full(),
127        )
128    }
129}
130
131impl Styled for Divider {
132    fn style(&mut self) -> &mut StyleRefinement {
133        &mut self.style
134    }
135}
136
137impl RenderOnce for Divider {
138    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
139        let mut base = match self.direction {
140            DividerDirection::Horizontal => div()
141                .min_w_0()
142                .h_px()
143                .max_h_px()
144                .w_full()
145                .when(self.inset, |this| this.mx_1p5()),
146            DividerDirection::Vertical => div()
147                .min_w_0()
148                .w_px()
149                .h_4()
150                .when(self.inset, |this| this.my_1p5()),
151        };
152
153        base.style().refine(&self.style);
154
155        match self.line_style {
156            DividerStyle::Solid => self.render_solid(base, cx).into_any_element(),
157            DividerStyle::Dashed => self.render_dashed(base).into_any_element(),
158        }
159    }
160}
161
162impl Component for Divider {
163    fn scope() -> ComponentScope {
164        ComponentScope::Layout
165    }
166
167    fn description() -> &'static str {
168        "Visual separator used to create divisions between groups of content \
169        or sections in a layout."
170    }
171
172    fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
173        v_flex()
174            .gap_6()
175            .children(vec![
176                example_group_with_title(
177                    "Horizontal Dividers",
178                    vec![
179                        single_example("Default", Divider::horizontal().into_any_element()),
180                        single_example(
181                            "Border Color",
182                            Divider::horizontal()
183                                .color(DividerColor::Border)
184                                .into_any_element(),
185                        ),
186                        single_example("Inset", Divider::horizontal().inset().into_any_element()),
187                        single_example("Dashed", Divider::horizontal_dashed().into_any_element()),
188                    ],
189                ),
190                example_group_with_title(
191                    "Vertical Dividers",
192                    vec![
193                        single_example(
194                            "Default",
195                            div().h_16().child(Divider::vertical()).into_any_element(),
196                        ),
197                        single_example(
198                            "Border Color",
199                            div()
200                                .h_16()
201                                .child(Divider::vertical().color(DividerColor::Border))
202                                .into_any_element(),
203                        ),
204                        single_example(
205                            "Inset",
206                            div()
207                                .h_16()
208                                .child(Divider::vertical().inset())
209                                .into_any_element(),
210                        ),
211                        single_example(
212                            "Dashed",
213                            div()
214                                .h_16()
215                                .child(Divider::vertical_dashed())
216                                .into_any_element(),
217                        ),
218                    ],
219                ),
220                example_group_with_title(
221                    "Example Usage",
222                    vec![single_example(
223                        "Between Content",
224                        v_flex()
225                            .w_full()
226                            .gap_4()
227                            .px_4()
228                            .child(Label::new("Section One"))
229                            .child(Divider::horizontal())
230                            .child(Label::new("Section Two"))
231                            .child(Divider::horizontal_dashed())
232                            .child(Label::new("Section Three"))
233                            .into_any_element(),
234                    )],
235                ),
236            ])
237            .into_any_element()
238    }
239}
240
Served at tenant.openagents/omega Member data and write actions are omitted.