icon.rs

  1use std::sync::Arc;
  2
  3use crate::theme::theme;
  4use crate::Theme;
  5use gpui2::elements::svg;
  6use gpui2::style::StyleHelpers;
  7use gpui2::{Element, ViewContext};
  8use gpui2::{Hsla, IntoElement};
  9
 10#[derive(Default, PartialEq, Copy, Clone)]
 11pub enum IconColor {
 12    #[default]
 13    Default,
 14    Muted,
 15    Disabled,
 16    Placeholder,
 17    Accent,
 18    Error,
 19    Warning,
 20    Success,
 21    Info,
 22}
 23
 24impl IconColor {
 25    pub fn color(self, theme: Arc<Theme>) -> Hsla {
 26        match self {
 27            IconColor::Default => theme.lowest.base.default.foreground,
 28            IconColor::Muted => theme.lowest.variant.default.foreground,
 29            IconColor::Disabled => theme.lowest.base.disabled.foreground,
 30            IconColor::Placeholder => theme.lowest.base.disabled.foreground,
 31            IconColor::Accent => theme.lowest.accent.default.foreground,
 32            IconColor::Error => theme.lowest.negative.default.foreground,
 33            IconColor::Warning => theme.lowest.warning.default.foreground,
 34            IconColor::Success => theme.lowest.positive.default.foreground,
 35            IconColor::Info => theme.lowest.accent.default.foreground,
 36        }
 37    }
 38}
 39
 40#[derive(Default, PartialEq, Copy, Clone)]
 41pub enum IconAsset {
 42    Ai,
 43    ArrowLeft,
 44    ArrowRight,
 45    ArrowUpRight,
 46    AudioOff,
 47    AudioOn,
 48    Bolt,
 49    ChevronDown,
 50    ChevronLeft,
 51    ChevronRight,
 52    ChevronUp,
 53    Close,
 54    ExclamationTriangle,
 55    File,
 56    FileDoc,
 57    FileGit,
 58    FileLock,
 59    FileRust,
 60    FileToml,
 61    FileTree,
 62    Folder,
 63    FolderOpen,
 64    FolderX,
 65    #[default]
 66    Hash,
 67    InlayHint,
 68    MagicWand,
 69    MagnifyingGlass,
 70    MessageBubbles,
 71    Mic,
 72    MicMute,
 73    Plus,
 74    Screen,
 75    Split,
 76    Terminal,
 77    XCircle,
 78    Copilot,
 79    Envelope,
 80}
 81
 82impl IconAsset {
 83    pub fn path(self) -> &'static str {
 84        match self {
 85            IconAsset::Ai => "icons/ai.svg",
 86            IconAsset::ArrowLeft => "icons/arrow_left.svg",
 87            IconAsset::ArrowRight => "icons/arrow_right.svg",
 88            IconAsset::ArrowUpRight => "icons/arrow_up_right.svg",
 89            IconAsset::AudioOff => "icons/speaker-off.svg",
 90            IconAsset::AudioOn => "icons/speaker-loud.svg",
 91            IconAsset::Bolt => "icons/bolt.svg",
 92            IconAsset::ChevronDown => "icons/chevron_down.svg",
 93            IconAsset::ChevronLeft => "icons/chevron_left.svg",
 94            IconAsset::ChevronRight => "icons/chevron_right.svg",
 95            IconAsset::ChevronUp => "icons/chevron_up.svg",
 96            IconAsset::Close => "icons/x.svg",
 97            IconAsset::ExclamationTriangle => "icons/warning.svg",
 98            IconAsset::File => "icons/file_icons/file.svg",
 99            IconAsset::FileDoc => "icons/file_icons/book.svg",
100            IconAsset::FileGit => "icons/file_icons/git.svg",
101            IconAsset::FileLock => "icons/file_icons/lock.svg",
102            IconAsset::FileRust => "icons/file_icons/rust.svg",
103            IconAsset::FileToml => "icons/file_icons/toml.svg",
104            IconAsset::FileTree => "icons/project.svg",
105            IconAsset::Folder => "icons/file_icons/folder.svg",
106            IconAsset::FolderOpen => "icons/file_icons/folder_open.svg",
107            IconAsset::FolderX => "icons/stop_sharing.svg",
108            IconAsset::Hash => "icons/hash.svg",
109            IconAsset::InlayHint => "icons/inlay_hint.svg",
110            IconAsset::MagicWand => "icons/magic-wand.svg",
111            IconAsset::MagnifyingGlass => "icons/magnifying_glass.svg",
112            IconAsset::MessageBubbles => "icons/conversations.svg",
113            IconAsset::Mic => "icons/mic.svg",
114            IconAsset::MicMute => "icons/mic-mute.svg",
115            IconAsset::Plus => "icons/plus.svg",
116            IconAsset::Screen => "icons/desktop.svg",
117            IconAsset::Split => "icons/split.svg",
118            IconAsset::Terminal => "icons/terminal.svg",
119            IconAsset::XCircle => "icons/error.svg",
120            IconAsset::Copilot => "icons/copilot.svg",
121            IconAsset::Envelope => "icons/feedback.svg",
122        }
123    }
124}
125
126#[derive(Element, Clone)]
127pub struct Icon {
128    asset: IconAsset,
129    color: IconColor,
130}
131
132pub fn icon(asset: IconAsset) -> Icon {
133    Icon {
134        asset,
135        color: IconColor::default(),
136    }
137}
138
139impl Icon {
140    pub fn color(mut self, color: IconColor) -> Self {
141        self.color = color;
142        self
143    }
144
145    fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
146        let theme = theme(cx);
147        let fill = self.color.color(theme);
148
149        svg()
150            .flex_none()
151            .path(self.asset.path())
152            .size_4()
153            .fill(fill)
154    }
155}