Properly add icon support into tree rendering

The icon to render is passed as an additonal field
and rendered directly to the surface so that the
style can be rendered as well
pull/11/head
trivernis 1 year ago
parent 7ccbea2a31
commit 8c87021a53
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -191,20 +191,17 @@ impl Explorer {
.ui
.as_ref()
.and_then(|s| s.get("file").cloned())
.map(|i| i.icon_char.to_string())
.unwrap_or(defaults.item);
let item = file_icon.clone();
let tree_closed = icons
.ui
.as_ref()
.and_then(|s| s.get("folder").cloned())
.map(|i| i.icon_char.to_string())
.unwrap_or(defaults.tree_closed);
let tree_opened = icons
.ui
.as_ref()
.and_then(|s| s.get("folder_opened").cloned())
.map(|i| i.icon_char.to_string())
.unwrap_or(defaults.tree_opened);
TreeIcons {
@ -212,14 +209,10 @@ impl Explorer {
tree_opened,
item,
icon_fn: Some(Arc::new(move |item| {
if let Some(file_type) = PathBuf::from(item).extension() {
icons
.icon_from_filetype(&file_type.to_string_lossy())
.map(|i| i.icon_char.to_string())
.unwrap_or_else(|| file_icon.to_owned())
} else {
file_icon.to_owned()
}
icons
.icon_from_path(Some(&PathBuf::from(item)))
.cloned()
.unwrap_or_else(|| file_icon.to_owned())
})),
}
}

@ -1,7 +1,7 @@
use std::{cmp::Ordering, sync::Arc};
use anyhow::Result;
use helix_view::theme::Modifier;
use helix_view::{icons::Icon, theme::Modifier};
use crate::{
compositor::{Component, Context, EventResult},
@ -782,6 +782,7 @@ struct RenderedLine {
content: String,
selected: bool,
is_ancestor_of_current_item: bool,
icon: Icon,
}
struct RenderTreeParams<'a, T> {
tree: &'a Tree<T>,
@ -793,18 +794,18 @@ struct RenderTreeParams<'a, T> {
#[derive(Clone)]
pub struct TreeIcons {
pub tree_closed: String,
pub tree_opened: String,
pub item: String,
pub icon_fn: Option<Arc<dyn Fn(&str) -> String>>,
pub tree_closed: Icon,
pub tree_opened: Icon,
pub item: Icon,
pub icon_fn: Option<Arc<dyn Fn(&str) -> Icon>>,
}
impl Default for TreeIcons {
fn default() -> Self {
Self {
tree_closed: String::from("⏵"),
tree_opened: String::from("⏷"),
item: String::from(" "),
tree_closed: Icon::unstyled('⏵'),
tree_opened: Icon::unstyled('⏷'),
item: Icon::unstyled(' '),
icon_fn: None,
}
}
@ -821,33 +822,31 @@ fn render_tree<T: TreeViewItem>(
) -> Vec<RenderedLine> {
let name = tree.item.name();
let indent = if level > 0 {
let indicator = if tree.item().is_parent() {
if tree.is_opened {
icons.tree_opened.to_owned()
} else {
icons.tree_closed.to_owned()
}
let icon = if tree.item().is_parent() {
if tree.is_opened {
icons.tree_opened.to_owned()
} else {
if let Some(icon_fn) = icons.icon_fn.as_ref() {
icon_fn(&name)
} else {
icons.item.to_owned()
}
};
format!("{}{} ", prefix, indicator)
icons.tree_closed.to_owned()
}
} else {
if let Some(icon_fn) = icons.icon_fn.as_ref() {
icon_fn(&name)
} else {
icons.item.clone()
icons.item.to_owned()
}
};
let indent = if level > 0 {
format!("{} ", prefix)
} else {
String::new()
};
let head = RenderedLine {
indent,
selected: selected == tree.index,
is_ancestor_of_current_item: selected != tree.index && tree.get(selected).is_some(),
content: name,
icon,
};
let prefix = format!("{}{}", prefix, if level == 0 { "" } else { " " });
vec![head]
@ -899,12 +898,20 @@ impl<T: TreeViewItem + Clone> TreeView<T> {
style,
);
let x = area.x.saturating_add(indent_len);
surface.set_stringn(
x,
area.y,
line.icon.icon_char.to_string(),
2,
line.icon.style.map(|s| s.into()).unwrap_or(style),
);
let style = if line.selected {
style.add_modifier(Modifier::REVERSED)
} else {
style
};
let x = area.x.saturating_add(indent_len);
let x = x.saturating_add(2);
surface.set_stringn(
x,
area.y,

@ -54,6 +54,13 @@ impl Icon {
self.style = Some(IconStyle::Default(style));
}
}
pub fn unstyled(icon_char: char) -> Self {
Self {
icon_char,
style: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]

Loading…
Cancel
Save