Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:34:24.195Z 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

image.rs

201 lines · 6.2 KB · rust
1use std::sync::Arc;
2
3use gpui::Transformation;
4use gpui::{App, IntoElement, Rems, RenderOnce, Size, Styled, Window, svg};
5use serde::{Deserialize, Serialize};
6use strum::{EnumIter, EnumString, IntoStaticStr};
7
8use crate::prelude::*;
9use crate::traits::transformable::Transformable;
10
11#[derive(
12    Debug, PartialEq, Eq, Copy, Clone, EnumIter, EnumString, IntoStaticStr, Serialize, Deserialize,
13)]
14#[strum(serialize_all = "snake_case")]
15pub enum VectorName {
16    BusinessStamp,
17    VipStamp,
18    Grid,
19    OmegaLogo,
20    ProTrialStamp,
21    ProUserStamp,
22    StudentStamp,
23}
24
25impl VectorName {
26    /// Returns the path to this vector image.
27    pub fn path(&self) -> Arc<str> {
28        let file_stem: &'static str = self.into();
29        format!("images/{file_stem}.svg").into()
30    }
31}
32
33/// A vector image, such as an SVG.
34///
35/// A [`Vector`] is different from an [`crate::Icon`] in that it is intended
36/// to be displayed at a specific size, or series of sizes, rather
37/// than conforming to the standard size of an icon.
38#[derive(IntoElement, RegisterComponent)]
39pub struct Vector {
40    path: Arc<str>,
41    color: Color,
42    size: Size<Rems>,
43    transformation: Transformation,
44}
45
46impl Vector {
47    /// Creates a new [`Vector`] image with the given [`VectorName`] and size.
48    pub fn new(vector: VectorName, width: Rems, height: Rems) -> Self {
49        Self {
50            path: vector.path(),
51            color: Color::default(),
52            size: Size { width, height },
53            transformation: Transformation::default(),
54        }
55    }
56
57    /// Creates a new [`Vector`] image where the width and height are the same.
58    pub fn square(vector: VectorName, size: Rems) -> Self {
59        Self::new(vector, size, size)
60    }
61
62    /// Sets the vector color.
63    pub fn color(mut self, color: Color) -> Self {
64        self.color = color;
65        self
66    }
67
68    /// Sets the vector size.
69    pub fn size(mut self, size: impl Into<Size<Rems>>) -> Self {
70        let size = size.into();
71        self.size = size;
72        self
73    }
74}
75
76impl Transformable for Vector {
77    fn transform(mut self, transformation: Transformation) -> Self {
78        self.transformation = transformation;
79        self
80    }
81}
82
83impl RenderOnce for Vector {
84    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
85        let width = self.size.width;
86        let height = self.size.height;
87
88        svg()
89            // By default, prevent the SVG from stretching
90            // to fill its container.
91            .flex_none()
92            .w(width)
93            .h(height)
94            .path(self.path)
95            .text_color(self.color.color(cx))
96            .with_transformation(self.transformation)
97    }
98}
99
100impl Component for Vector {
101    fn scope() -> ComponentScope {
102        ComponentScope::Images
103    }
104
105    fn name() -> &'static str {
106        "Vector"
107    }
108
109    fn description() -> &'static str {
110        "A vector image component that can be displayed at specific sizes."
111    }
112
113    fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
114        let size = rems_from_px(60.);
115
116        v_flex()
117            .gap_6()
118            .children(vec![
119                example_group_with_title(
120                    "Basic Usage",
121                    vec![
122                        single_example(
123                            "Default",
124                            Vector::square(VectorName::OmegaLogo, size).into_any_element(),
125                        ),
126                        single_example(
127                            "Custom Size",
128                            h_flex()
129                                .h(rems_from_px(120.))
130                                .justify_center()
131                                .child(Vector::new(
132                                    VectorName::OmegaLogo,
133                                    rems_from_px(120.),
134                                    rems_from_px(200.),
135                                ))
136                                .into_any_element(),
137                        ),
138                    ],
139                ),
140                example_group_with_title(
141                    "Colored",
142                    vec![
143                        single_example(
144                            "Accent Color",
145                            Vector::square(VectorName::OmegaLogo, size)
146                                .color(Color::Accent)
147                                .into_any_element(),
148                        ),
149                        single_example(
150                            "Error Color",
151                            Vector::square(VectorName::OmegaLogo, size)
152                                .color(Color::Error)
153                                .into_any_element(),
154                        ),
155                    ],
156                ),
157                example_group_with_title(
158                    "Different Vectors",
159                    vec![single_example(
160                        "Grid",
161                        Vector::square(VectorName::Grid, rems_from_px(100.)).into_any_element(),
162                    )],
163                ),
164            ])
165            .into_any_element()
166    }
167}
168
169#[cfg(test)]
170mod tests {
171    use super::*;
172
173    #[test]
174    fn vector_path() {
175        assert_eq!(
176            VectorName::OmegaLogo.path().as_ref(),
177            "images/omega_logo.svg"
178        );
179        assert_eq!(VectorName::Grid.path().as_ref(), "images/grid.svg");
180    }
181
182    /// OMEGA-DELTA-0022. `assets/images/` was outside every brand gate, so
183    /// `zed_logo.svg` and `zed_x_copilot.svg` were embedded in the signed
184    /// `0.2.0-rc11` binary and the Zed `Z` rendered through this component in
185    /// the release command palette. Neither the artwork nor a name to restore
186    /// it under may come back.
187    #[test]
188    fn no_vector_name_carries_a_competitor_name() {
189        use strum::IntoEnumIterator as _;
190
191        for vector in VectorName::iter() {
192            let path = vector.path();
193            let name: &'static str = vector.into();
194            assert!(
195                !path.contains("zed"),
196                "VectorName::{name:?} resolves to a competitor-named asset: {path}"
197            );
198        }
199    }
200}
201
Served at tenant.openagents/omega Member data and write actions are omitted.