icon.rs

  1use gpui::{svg, IntoElement, Rems, Transformation};
  2use strum::EnumIter;
  3
  4use crate::prelude::*;
  5
  6#[derive(Default, PartialEq, Copy, Clone)]
  7pub enum IconSize {
  8    Indicator,
  9    XSmall,
 10    Small,
 11    #[default]
 12    Medium,
 13}
 14
 15impl IconSize {
 16    pub fn rems(self) -> Rems {
 17        match self {
 18            IconSize::Indicator => rems_from_px(10.),
 19            IconSize::XSmall => rems_from_px(12.),
 20            IconSize::Small => rems_from_px(14.),
 21            IconSize::Medium => rems_from_px(16.),
 22        }
 23    }
 24}
 25
 26#[derive(Debug, PartialEq, Copy, Clone, EnumIter)]
 27pub enum IconName {
 28    Ai,
 29    ArrowDown,
 30    ArrowLeft,
 31    ArrowRight,
 32    ArrowUp,
 33    ArrowUpRight,
 34    ArrowCircle,
 35    AtSign,
 36    AudioOff,
 37    AudioOn,
 38    Backspace,
 39    Bell,
 40    BellOff,
 41    BellRing,
 42    BellDot,
 43    Bolt,
 44    CaseSensitive,
 45    Check,
 46    ChevronDown,
 47    ChevronLeft,
 48    ChevronRight,
 49    ChevronUp,
 50    Close,
 51    Collab,
 52    Command,
 53    Control,
 54    Copilot,
 55    CopilotDisabled,
 56    CopilotError,
 57    CopilotInit,
 58    Copy,
 59    Dash,
 60    Delete,
 61    Disconnected,
 62    Ellipsis,
 63    Envelope,
 64    Escape,
 65    ExclamationTriangle,
 66    Exit,
 67    ExternalLink,
 68    File,
 69    FileDoc,
 70    FileGeneric,
 71    FileGit,
 72    FileLock,
 73    FileRust,
 74    FileToml,
 75    FileTree,
 76    Filter,
 77    Folder,
 78    FolderOpen,
 79    FolderX,
 80    Github,
 81    Hash,
 82    InlayHint,
 83    Link,
 84    MagicWand,
 85    MagnifyingGlass,
 86    MailOpen,
 87    Maximize,
 88    Menu,
 89    MessageBubbles,
 90    Mic,
 91    MicMute,
 92    Minimize,
 93    Option,
 94    PageDown,
 95    PageUp,
 96    Pencil,
 97    Play,
 98    Plus,
 99    Public,
100    Quote,
101    Regex,
102    Replace,
103    ReplaceAll,
104    ReplaceNext,
105    Return,
106    ReplyArrowRight,
107    Settings,
108    Sliders,
109    Screen,
110    SelectAll,
111    Server,
112    Shift,
113    Snip,
114    Space,
115    Split,
116    Tab,
117    Terminal,
118    Trash,
119    Update,
120    WholeWord,
121    XCircle,
122    ZedXCopilot,
123}
124
125impl IconName {
126    pub fn path(self) -> &'static str {
127        match self {
128            IconName::Ai => "icons/ai.svg",
129            IconName::ArrowDown => "icons/arrow_down.svg",
130            IconName::ArrowLeft => "icons/arrow_left.svg",
131            IconName::ArrowRight => "icons/arrow_right.svg",
132            IconName::ArrowUp => "icons/arrow_up.svg",
133            IconName::ArrowUpRight => "icons/arrow_up_right.svg",
134            IconName::ArrowCircle => "icons/arrow_circle.svg",
135            IconName::AtSign => "icons/at_sign.svg",
136            IconName::AudioOff => "icons/speaker_off.svg",
137            IconName::AudioOn => "icons/speaker_loud.svg",
138            IconName::Backspace => "icons/backspace.svg",
139            IconName::Bell => "icons/bell.svg",
140            IconName::BellOff => "icons/bell_off.svg",
141            IconName::BellRing => "icons/bell_ring.svg",
142            IconName::BellDot => "icons/bell_dot.svg",
143            IconName::Bolt => "icons/bolt.svg",
144            IconName::CaseSensitive => "icons/case_insensitive.svg",
145            IconName::Check => "icons/check.svg",
146            IconName::ChevronDown => "icons/chevron_down.svg",
147            IconName::ChevronLeft => "icons/chevron_left.svg",
148            IconName::ChevronRight => "icons/chevron_right.svg",
149            IconName::ChevronUp => "icons/chevron_up.svg",
150            IconName::Close => "icons/x.svg",
151            IconName::Collab => "icons/user_group_16.svg",
152            IconName::Command => "icons/command.svg",
153            IconName::Control => "icons/control.svg",
154            IconName::Copilot => "icons/copilot.svg",
155            IconName::CopilotDisabled => "icons/copilot_disabled.svg",
156            IconName::CopilotError => "icons/copilot_error.svg",
157            IconName::CopilotInit => "icons/copilot_init.svg",
158            IconName::Copy => "icons/copy.svg",
159            IconName::Dash => "icons/dash.svg",
160            IconName::Delete => "icons/delete.svg",
161            IconName::Disconnected => "icons/disconnected.svg",
162            IconName::Ellipsis => "icons/ellipsis.svg",
163            IconName::Envelope => "icons/feedback.svg",
164            IconName::Escape => "icons/escape.svg",
165            IconName::ExclamationTriangle => "icons/warning.svg",
166            IconName::Exit => "icons/exit.svg",
167            IconName::ExternalLink => "icons/external_link.svg",
168            IconName::File => "icons/file.svg",
169            IconName::FileDoc => "icons/file_icons/book.svg",
170            IconName::FileGeneric => "icons/file_icons/file.svg",
171            IconName::FileGit => "icons/file_icons/git.svg",
172            IconName::FileLock => "icons/file_icons/lock.svg",
173            IconName::FileRust => "icons/file_icons/rust.svg",
174            IconName::FileToml => "icons/file_icons/toml.svg",
175            IconName::FileTree => "icons/project.svg",
176            IconName::Filter => "icons/filter.svg",
177            IconName::Folder => "icons/file_icons/folder.svg",
178            IconName::FolderOpen => "icons/file_icons/folder_open.svg",
179            IconName::FolderX => "icons/stop_sharing.svg",
180            IconName::Github => "icons/github.svg",
181            IconName::Hash => "icons/hash.svg",
182            IconName::InlayHint => "icons/inlay_hint.svg",
183            IconName::Link => "icons/link.svg",
184            IconName::MagicWand => "icons/magic_wand.svg",
185            IconName::MagnifyingGlass => "icons/magnifying_glass.svg",
186            IconName::MailOpen => "icons/mail_open.svg",
187            IconName::Maximize => "icons/maximize.svg",
188            IconName::Menu => "icons/menu.svg",
189            IconName::MessageBubbles => "icons/conversations.svg",
190            IconName::Mic => "icons/mic.svg",
191            IconName::MicMute => "icons/mic_mute.svg",
192            IconName::Minimize => "icons/minimize.svg",
193            IconName::Option => "icons/option.svg",
194            IconName::PageDown => "icons/page_down.svg",
195            IconName::PageUp => "icons/page_up.svg",
196            IconName::Pencil => "icons/pencil.svg",
197            IconName::Play => "icons/play.svg",
198            IconName::Plus => "icons/plus.svg",
199            IconName::Public => "icons/public.svg",
200            IconName::Quote => "icons/quote.svg",
201            IconName::Regex => "icons/regex.svg",
202            IconName::Replace => "icons/replace.svg",
203            IconName::ReplaceAll => "icons/replace_all.svg",
204            IconName::ReplaceNext => "icons/replace_next.svg",
205            IconName::Return => "icons/return.svg",
206            IconName::ReplyArrowRight => "icons/reply_arrow_right.svg",
207            IconName::Settings => "icons/file_icons/settings.svg",
208            IconName::Sliders => "icons/sliders.svg",
209            IconName::Screen => "icons/desktop.svg",
210            IconName::SelectAll => "icons/select_all.svg",
211            IconName::Server => "icons/server.svg",
212            IconName::Shift => "icons/shift.svg",
213            IconName::Snip => "icons/snip.svg",
214            IconName::Space => "icons/space.svg",
215            IconName::Split => "icons/split.svg",
216            IconName::Tab => "icons/tab.svg",
217            IconName::Terminal => "icons/terminal.svg",
218            IconName::Trash => "icons/trash.svg",
219            IconName::Update => "icons/update.svg",
220            IconName::WholeWord => "icons/word_search.svg",
221            IconName::XCircle => "icons/error.svg",
222            IconName::ZedXCopilot => "icons/zed_x_copilot.svg",
223        }
224    }
225}
226
227#[derive(IntoElement)]
228pub struct Icon {
229    path: SharedString,
230    color: Color,
231    size: IconSize,
232    transformation: Transformation,
233}
234
235impl Icon {
236    pub fn new(icon: IconName) -> Self {
237        Self {
238            path: icon.path().into(),
239            color: Color::default(),
240            size: IconSize::default(),
241            transformation: Transformation::default(),
242        }
243    }
244
245    pub fn from_path(path: impl Into<SharedString>) -> Self {
246        Self {
247            path: path.into(),
248            color: Color::default(),
249            size: IconSize::default(),
250            transformation: Transformation::default(),
251        }
252    }
253
254    pub fn color(mut self, color: Color) -> Self {
255        self.color = color;
256        self
257    }
258
259    pub fn size(mut self, size: IconSize) -> Self {
260        self.size = size;
261        self
262    }
263
264    pub fn transform(mut self, transformation: Transformation) -> Self {
265        self.transformation = transformation;
266        self
267    }
268}
269
270impl RenderOnce for Icon {
271    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
272        svg()
273            .with_transformation(self.transformation)
274            .size(self.size.rems())
275            .flex_none()
276            .path(self.path)
277            .text_color(self.color.color(cx))
278    }
279}