Compare commits

...

7 Commits

Author SHA1 Message Date
Richard Feldman
23f698a219 Eliminate some duplicate map()s 2025-12-09 15:11:17 -05:00
Richard Feldman
29686f52cb Update call sites for icons 2025-12-09 15:09:09 -05:00
Richard Feldman
9e731486f0 Rename to from_embedded 2025-12-09 15:01:25 -05:00
Richard Feldman
f391db3def Revert "Delete unused from_embededd fn"
This reverts commit 65a4189557.
2025-12-09 14:59:48 -05:00
Richard Feldman
65a4189557 Delete unused from_embededd fn 2025-12-09 14:59:01 -05:00
Richard Feldman
b648cf9fb7 Remove unnecessary named var 2025-12-09 14:57:45 -05:00
Richard Feldman
457aee7170 Don't use a heuristic for icon path 2025-12-09 14:55:58 -05:00
20 changed files with 56 additions and 53 deletions

View File

@@ -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)

View 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),
)

View File

@@ -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

View File

@@ -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)),
)
}
}

View File

@@ -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),

View File

@@ -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()

View File

@@ -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")

View File

@@ -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 {

View File

@@ -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(

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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))
}
}

View File

@@ -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

View File

@@ -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()
})

View File

@@ -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))
}
}

View File

@@ -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)),
)
})

View File

@@ -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)))
}

View File

@@ -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 { .. }) {

View File

@@ -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),
)

View File

@@ -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(),