Compare commits
7 Commits
fix_devcon
...
icon-path
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23f698a219 | ||
|
|
29686f52cb | ||
|
|
9e731486f0 | ||
|
|
f391db3def | ||
|
|
65a4189557 | ||
|
|
b648cf9fb7 | ||
|
|
457aee7170 |
@@ -2539,7 +2539,7 @@ impl AcpThreadView {
|
||||
|
||||
let tool_icon = if tool_call.kind == acp::ToolKind::Edit && has_location {
|
||||
FileIcons::get_icon(&tool_call.locations[0].path, cx)
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
.unwrap_or(Icon::new(IconName::ToolPencil))
|
||||
} else {
|
||||
Icon::new(match tool_call.kind {
|
||||
@@ -4034,7 +4034,7 @@ impl AcpThreadView {
|
||||
});
|
||||
|
||||
let file_icon = FileIcons::get_icon(path.as_std_path(), cx)
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
.map(|icon| icon.color(Color::Muted).size(IconSize::Small))
|
||||
.unwrap_or_else(|| {
|
||||
Icon::new(IconName::File)
|
||||
|
||||
@@ -762,7 +762,7 @@ fn render_fold_icon_button(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Icon::from_path(icon_path.clone())
|
||||
Icon::from_embedded(icon_path.clone())
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
@@ -975,7 +975,7 @@ impl Render for LoadingContext {
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Icon::from_path(self.icon.clone())
|
||||
Icon::from_embedded(self.icon.clone())
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
|
||||
@@ -2427,7 +2427,7 @@ fn render_fold_icon_button(
|
||||
ButtonLike::new(fold_id)
|
||||
.style(ButtonStyle::Filled)
|
||||
.layer(ElevationIndex::ElevatedSurface)
|
||||
.child(Icon::from_path(icon_path.clone()))
|
||||
.child(Icon::from_embedded(icon_path.clone()))
|
||||
.child(Label::new(label.clone()).single_line())
|
||||
.on_click(move |_, window, cx| {
|
||||
editor
|
||||
|
||||
@@ -165,7 +165,7 @@ impl PickerDelegate for ContactFinderDelegate {
|
||||
.toggle_state(selected)
|
||||
.start_slot(Avatar::new(user.avatar_uri.clone()))
|
||||
.child(Label::new(user.github_login.clone()))
|
||||
.end_slot::<Icon>(icon_path.map(Icon::from_path)),
|
||||
.end_slot::<Icon>(icon_path.map(Icon::from_embedded)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1487,7 +1487,7 @@ impl PickerDelegate for DebugDelegate {
|
||||
let language_icon = language_name.as_ref().and_then(|lang| {
|
||||
file_icons::FileIcons::get(cx)
|
||||
.get_icon_for_type(&lang.0.to_lowercase(), cx)
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
});
|
||||
|
||||
let (icon, indicator) = match task_kind {
|
||||
@@ -1497,7 +1497,7 @@ impl PickerDelegate for DebugDelegate {
|
||||
Some(TaskSourceKind::Lsp { language_name, .. }) => (
|
||||
file_icons::FileIcons::get(cx)
|
||||
.get_icon_for_type(&language_name.to_lowercase(), cx)
|
||||
.map(Icon::from_path),
|
||||
.map(Icon::from_embedded),
|
||||
Some(Indicator::icon(
|
||||
Icon::new(IconName::BoltFilled)
|
||||
.color(Color::Muted)
|
||||
@@ -1507,7 +1507,7 @@ impl PickerDelegate for DebugDelegate {
|
||||
Some(TaskSourceKind::Language { name }) => (
|
||||
file_icons::FileIcons::get(cx)
|
||||
.get_icon_for_type(&name.to_lowercase(), cx)
|
||||
.map(Icon::from_path),
|
||||
.map(Icon::from_embedded),
|
||||
None,
|
||||
),
|
||||
None => (Some(Icon::new(IconName::HistoryRerun)), None),
|
||||
|
||||
@@ -904,7 +904,7 @@ impl CompletionsMenu {
|
||||
})
|
||||
.or_else(|| {
|
||||
completion.icon_path.as_ref().map(|path| {
|
||||
Icon::from_path(path)
|
||||
Icon::from_embedded(path)
|
||||
.size(IconSize::XSmall)
|
||||
.color(Color::Muted)
|
||||
.into_any_element()
|
||||
|
||||
@@ -3989,7 +3989,7 @@ impl EditorElement {
|
||||
let editor = self.editor.clone();
|
||||
let buffer_id = for_excerpt.buffer_id;
|
||||
let toggle_chevron_icon =
|
||||
FileIcons::get_chevron_icon(!is_folded, cx).map(Icon::from_path);
|
||||
FileIcons::get_chevron_icon(!is_folded, cx).map(Icon::from_embedded);
|
||||
let button_size = rems_from_px(28.);
|
||||
|
||||
header.child(
|
||||
@@ -4089,7 +4089,7 @@ impl EditorElement {
|
||||
let icon =
|
||||
FileIcons::get_icon(path, cx).unwrap_or_default();
|
||||
|
||||
el.child(Icon::from_path(icon).color(Color::Muted))
|
||||
el.child(Icon::from_embedded(icon).color(Color::Muted))
|
||||
})
|
||||
.child(
|
||||
ButtonLike::new("filename-button")
|
||||
|
||||
@@ -674,7 +674,7 @@ impl Item for Editor {
|
||||
.and_then(|path| FileIcons::get_icon(Path::new(&*path), cx))
|
||||
})
|
||||
.flatten()
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
}
|
||||
|
||||
fn tab_content(&self, params: TabContentParams, _: &Window, cx: &App) -> AnyElement {
|
||||
|
||||
@@ -1638,7 +1638,7 @@ impl PickerDelegate for FileFinderDelegate {
|
||||
let abs_path = path_match.abs_path(&self.project, cx)?;
|
||||
let file_name = abs_path.file_name()?;
|
||||
let icon = FileIcons::get_icon(file_name.as_ref(), cx)?;
|
||||
Some(Icon::from_path(icon).color(Color::Muted))
|
||||
Some(Icon::from_embedded(icon).color(Color::Muted))
|
||||
});
|
||||
|
||||
Some(
|
||||
|
||||
@@ -711,7 +711,7 @@ impl PickerDelegate for OpenPathDelegate {
|
||||
} else {
|
||||
FileIcons::get_icon(path, cx)?
|
||||
};
|
||||
Some(Icon::from_path(icon).color(Color::Muted))
|
||||
Some(Icon::from_embedded(icon).color(Color::Muted))
|
||||
});
|
||||
|
||||
match &self.directory_state {
|
||||
|
||||
@@ -151,7 +151,7 @@ impl Item for ImageView {
|
||||
.file_icons
|
||||
.then(|| FileIcons::get_icon(&path, cx))
|
||||
.flatten()
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
}
|
||||
|
||||
fn breadcrumb_location(&self, cx: &App) -> ToolbarItemLocation {
|
||||
|
||||
@@ -177,8 +177,7 @@ impl LanguageSelectorDelegate {
|
||||
.path_suffixes
|
||||
.iter()
|
||||
.find_map(|extension| FileIcons::get_icon(Path::new(extension), cx))
|
||||
.map(Icon::from_path)
|
||||
.map(|icon| icon.color(Color::Muted))
|
||||
.map(|path| Icon::from_embedded(path).color(Color::Muted))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2150,8 +2150,11 @@ impl OutlinePanel {
|
||||
.contains(&CollapsedEntry::Excerpt(excerpt.buffer_id, excerpt.id));
|
||||
let color = entry_label_color(is_active);
|
||||
let icon = if has_outlines {
|
||||
FileIcons::get_chevron_icon(is_expanded, cx)
|
||||
.map(|icon_path| Icon::from_path(icon_path).color(color).into_any_element())
|
||||
FileIcons::get_chevron_icon(is_expanded, cx).map(|icon_path| {
|
||||
Icon::from_embedded(icon_path)
|
||||
.color(color)
|
||||
.into_any_element()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -2237,7 +2240,7 @@ impl OutlinePanel {
|
||||
let icon = if has_children {
|
||||
FileIcons::get_chevron_icon(is_expanded, cx)
|
||||
.map(|icon_path| {
|
||||
Icon::from_path(icon_path)
|
||||
Icon::from_embedded(icon_path)
|
||||
.color(entry_label_color(is_active))
|
||||
.into_any_element()
|
||||
})
|
||||
@@ -2279,8 +2282,11 @@ impl OutlinePanel {
|
||||
let color =
|
||||
entry_git_aware_label_color(entry.git_summary, entry.is_ignored, is_active);
|
||||
let icon = if settings.file_icons {
|
||||
FileIcons::get_icon(entry.path.as_std_path(), cx)
|
||||
.map(|icon_path| Icon::from_path(icon_path).color(color).into_any_element())
|
||||
FileIcons::get_icon(entry.path.as_std_path(), cx).map(|icon_path| {
|
||||
Icon::from_embedded(icon_path)
|
||||
.color(color)
|
||||
.into_any_element()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -2314,8 +2320,7 @@ impl OutlinePanel {
|
||||
} else {
|
||||
FileIcons::get_chevron_icon(is_expanded, cx)
|
||||
}
|
||||
.map(Icon::from_path)
|
||||
.map(|icon| icon.color(color).into_any_element());
|
||||
.map(|path| Icon::from_embedded(path).color(color).into_any_element());
|
||||
(
|
||||
ElementId::from(directory.entry.id.to_proto() as usize),
|
||||
HighlightedLabel::new(
|
||||
@@ -2340,8 +2345,7 @@ impl OutlinePanel {
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.map(Icon::from_path)
|
||||
.map(|icon| icon.color(color).into_any_element());
|
||||
.map(|path| Icon::from_embedded(path).color(color).into_any_element());
|
||||
(icon, file_name(path.as_std_path()))
|
||||
}
|
||||
None => (None, "Untitled".to_string()),
|
||||
@@ -2411,8 +2415,7 @@ impl OutlinePanel {
|
||||
} else {
|
||||
FileIcons::get_chevron_icon(is_expanded, cx)
|
||||
}
|
||||
.map(Icon::from_path)
|
||||
.map(|icon| icon.color(color).into_any_element());
|
||||
.map(|path| Icon::from_embedded(path).color(color).into_any_element());
|
||||
(
|
||||
ElementId::from(
|
||||
folded_dir
|
||||
|
||||
@@ -4869,7 +4869,7 @@ impl ProjectPanel {
|
||||
.unwrap_or(false);
|
||||
div().child(
|
||||
DecoratedIcon::new(
|
||||
Icon::from_path(icon.clone()).color(Color::Muted),
|
||||
Icon::from_embedded(icon.clone()).color(Color::Muted),
|
||||
Some(
|
||||
IconDecoration::new(
|
||||
if kind.is_file() {
|
||||
@@ -4896,7 +4896,7 @@ impl ProjectPanel {
|
||||
.into_any_element(),
|
||||
)
|
||||
} else {
|
||||
h_flex().child(Icon::from_path(icon.to_string()).color(Color::Muted))
|
||||
h_flex().child(Icon::from_embedded(icon.to_string()).color(Color::Muted))
|
||||
}
|
||||
} else if let Some((icon_name, color)) =
|
||||
entry_diagnostic_aware_icon_name_and_color(diagnostic_severity)
|
||||
@@ -6110,7 +6110,7 @@ impl Render for DraggedProjectEntryView {
|
||||
this.child(Label::new(format!("{} entries", self.selections.len())))
|
||||
} else {
|
||||
this.child(if let Some(icon) = &self.icon {
|
||||
div().child(Icon::from_path(icon.clone()))
|
||||
div().child(Icon::from_embedded(icon.clone()))
|
||||
} else {
|
||||
div()
|
||||
})
|
||||
|
||||
@@ -71,7 +71,7 @@ impl KernelSpecification {
|
||||
|
||||
file_icons::FileIcons::get(cx)
|
||||
.get_icon_for_type(&lang_name.to_lowercase(), cx)
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
.unwrap_or(Icon::new(IconName::ReplNeutral))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +191,7 @@ impl ScopeSelectorDelegate {
|
||||
.iter()
|
||||
.find_map(|extension| FileIcons::get_icon(Path::new(extension), cx))
|
||||
.or(FileIcons::get(cx).get_icon_for_type("default", cx))
|
||||
.map(Icon::from_path)
|
||||
.map(|icon| icon.color(Color::Muted))
|
||||
.map(|path| Icon::from_embedded(path).color(Color::Muted))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +332,7 @@ impl PickerDelegate for ScopeSelectorDelegate {
|
||||
.and_then(|available_language| self.scope_icon(available_language.matcher(), cx))
|
||||
.or_else(|| {
|
||||
Some(
|
||||
Icon::from_path(IconName::ToolWeb.path())
|
||||
Icon::from_embedded(IconName::ToolWeb.path())
|
||||
.map(|icon| icon.color(Color::Muted)),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -321,7 +321,7 @@ impl Item for SvgPreviewView {
|
||||
.as_ref()
|
||||
.and_then(|buffer| buffer.read(cx).file())
|
||||
.and_then(|file| FileIcons::get_icon(file.path().as_std_path(), cx))
|
||||
.map(Icon::from_path)
|
||||
.map(Icon::from_embedded)
|
||||
.or_else(|| Some(Icon::new(IconName::Image)))
|
||||
}
|
||||
|
||||
|
||||
@@ -495,7 +495,7 @@ impl PickerDelegate for TasksModalDelegate {
|
||||
}
|
||||
| TaskSourceKind::Language { name, .. } => file_icons::FileIcons::get(cx)
|
||||
.get_icon_for_type(&name.to_lowercase(), cx)
|
||||
.map(Icon::from_path),
|
||||
.map(Icon::from_embedded),
|
||||
}
|
||||
.map(|icon| icon.color(Color::Muted).size(IconSize::Small));
|
||||
let indicator = if matches!(source_kind, TaskSourceKind::Lsp { .. }) {
|
||||
|
||||
@@ -981,7 +981,7 @@ impl ContextMenu {
|
||||
*icon_position == IconPosition::Start && toggle.is_none(),
|
||||
|flex| {
|
||||
flex.child(
|
||||
Icon::from_path(custom_path.clone())
|
||||
Icon::from_embedded(custom_path.clone())
|
||||
.size(*icon_size)
|
||||
.color(icon_color),
|
||||
)
|
||||
@@ -990,7 +990,7 @@ impl ContextMenu {
|
||||
.child(Label::new(label.clone()).color(label_color).truncate())
|
||||
.when(*icon_position == IconPosition::End, |flex| {
|
||||
flex.child(
|
||||
Icon::from_path(custom_path.clone())
|
||||
Icon::from_embedded(custom_path.clone())
|
||||
.size(*icon_size)
|
||||
.color(icon_color),
|
||||
)
|
||||
|
||||
@@ -126,17 +126,6 @@ enum IconSource {
|
||||
ExternalSvg(SharedString),
|
||||
}
|
||||
|
||||
impl IconSource {
|
||||
fn from_path(path: impl Into<SharedString>) -> Self {
|
||||
let path = path.into();
|
||||
if path.starts_with("icons/") {
|
||||
Self::Embedded(path)
|
||||
} else {
|
||||
Self::External(Arc::from(PathBuf::from(path.as_ref())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(IntoElement, RegisterComponent)]
|
||||
pub struct Icon {
|
||||
source: IconSource,
|
||||
@@ -155,9 +144,22 @@ impl Icon {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_path(path: impl Into<SharedString>) -> Self {
|
||||
/// Create an icon from an embedded SVG path (e.g., "icons/ai.svg").
|
||||
/// These are SVGs bundled in the Zed binary.
|
||||
pub fn from_embedded(path: impl Into<SharedString>) -> Self {
|
||||
Self {
|
||||
source: IconSource::from_path(path),
|
||||
source: IconSource::Embedded(path.into()),
|
||||
color: Color::default(),
|
||||
size: IconSize::default().rems(),
|
||||
transformation: Transformation::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an icon from an external file path (e.g., from an extension).
|
||||
/// This renders the file as a raster image.
|
||||
pub fn from_external(path: impl Into<SharedString>) -> Self {
|
||||
Self {
|
||||
source: IconSource::External(Arc::from(PathBuf::from(path.into().as_ref()))),
|
||||
color: Color::default(),
|
||||
size: IconSize::default().rems(),
|
||||
transformation: Transformation::default(),
|
||||
|
||||
Reference in New Issue
Block a user