Skip to repository content201 lines · 6.2 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:43:01.006Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
image.rs
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