Make list_item toggleable
, improve optional left_icon
on list item
Co-Authored-By: Julia <30666851+ForLoveOfCats@users.noreply.github.com>
This commit is contained in:
parent
7e300079ce
commit
748ad5f05a
4 changed files with 73 additions and 30 deletions
|
@ -47,3 +47,9 @@ pub enum SelectedState {
|
||||||
PartiallySelected,
|
PartiallySelected,
|
||||||
Selected,
|
Selected,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum ToggleState {
|
||||||
|
Toggled,
|
||||||
|
NotToggled,
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::prelude::InteractionState;
|
use crate::prelude::{InteractionState, ToggleState};
|
||||||
use crate::theme::theme;
|
use crate::theme::theme;
|
||||||
use crate::ui::{icon, IconAsset, Label};
|
use crate::ui::{icon, IconAsset, Label};
|
||||||
use gpui2::geometry::rems;
|
use gpui2::geometry::rems;
|
||||||
|
@ -12,6 +12,7 @@ pub struct ListItem {
|
||||||
left_icon: Option<IconAsset>,
|
left_icon: Option<IconAsset>,
|
||||||
indent_level: f32,
|
indent_level: f32,
|
||||||
state: InteractionState,
|
state: InteractionState,
|
||||||
|
toggle: Option<ToggleState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_item(label: Label) -> ListItem {
|
pub fn list_item(label: Label) -> ListItem {
|
||||||
|
@ -20,6 +21,7 @@ pub fn list_item(label: Label) -> ListItem {
|
||||||
indent_level: 0.0,
|
indent_level: 0.0,
|
||||||
left_icon: None,
|
left_icon: None,
|
||||||
state: InteractionState::default(),
|
state: InteractionState::default(),
|
||||||
|
toggle: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,10 +30,17 @@ impl ListItem {
|
||||||
self.indent_level = indent_level;
|
self.indent_level = indent_level;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_toggle(mut self, toggle: ToggleState) -> Self {
|
||||||
|
self.toggle = Some(toggle);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn left_icon(mut self, left_icon: Option<IconAsset>) -> Self {
|
pub fn left_icon(mut self, left_icon: Option<IconAsset>) -> Self {
|
||||||
self.left_icon = left_icon;
|
self.left_icon = left_icon;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(mut self, state: InteractionState) -> Self {
|
pub fn state(mut self, state: InteractionState) -> Self {
|
||||||
self.state = state;
|
self.state = state;
|
||||||
self
|
self
|
||||||
|
@ -40,7 +49,7 @@ impl ListItem {
|
||||||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||||
let theme = theme(cx);
|
let theme = theme(cx);
|
||||||
|
|
||||||
let mut el = div()
|
div()
|
||||||
.fill(theme.middle.base.default.background)
|
.fill(theme.middle.base.default.background)
|
||||||
.hover()
|
.hover()
|
||||||
.fill(theme.middle.base.hovered.background)
|
.fill(theme.middle.base.hovered.background)
|
||||||
|
@ -53,13 +62,14 @@ impl ListItem {
|
||||||
.ml(rems(0.75 * self.indent_level.clone()))
|
.ml(rems(0.75 * self.indent_level.clone()))
|
||||||
.flex()
|
.flex()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.items_center(),
|
.items_center()
|
||||||
);
|
.children(match self.toggle {
|
||||||
|
Some(ToggleState::NotToggled) => Some(icon(IconAsset::ChevronRight)),
|
||||||
if self.left_icon.is_some() {
|
Some(ToggleState::Toggled) => Some(icon(IconAsset::ChevronDown)),
|
||||||
el = el.child(icon(self.left_icon.clone().unwrap()))
|
None => None,
|
||||||
}
|
})
|
||||||
|
.children(self.left_icon.map(|i| icon(i)))
|
||||||
el.child(self.label.clone())
|
.child(self.label.clone()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use crate::theme::theme;
|
use crate::theme::theme;
|
||||||
use gpui2::elements::svg;
|
use gpui2::elements::svg;
|
||||||
use gpui2::style::StyleHelpers;
|
use gpui2::style::StyleHelpers;
|
||||||
use gpui2::IntoElement;
|
use gpui2::IntoElement;
|
||||||
use gpui2::{Element, ViewContext};
|
use gpui2::{Element, ViewContext};
|
||||||
|
|
||||||
|
// Icon::Hash
|
||||||
|
// icon(IconAsset::Hash).color(IconColor::Warning)
|
||||||
|
// Icon::new(IconAsset::Hash).color(IconColor::Warning)
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Copy, Clone)]
|
#[derive(Default, PartialEq, Copy, Clone)]
|
||||||
pub enum IconAsset {
|
pub enum IconAsset {
|
||||||
Ai,
|
Ai,
|
||||||
|
@ -18,19 +20,29 @@ pub enum IconAsset {
|
||||||
File,
|
File,
|
||||||
Folder,
|
Folder,
|
||||||
FolderOpen,
|
FolderOpen,
|
||||||
|
ChevronDown,
|
||||||
|
ChevronUp,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn icon_asset(asset: IconAsset) -> impl Into<Cow<'static, str>> {
|
impl IconAsset {
|
||||||
match asset {
|
pub fn path(self) -> &'static str {
|
||||||
IconAsset::Ai => "icons/ai.svg",
|
match self {
|
||||||
IconAsset::ArrowLeft => "icons/arrow_left.svg",
|
IconAsset::Ai => "icons/ai.svg",
|
||||||
IconAsset::ArrowRight => "icons/arrow_right.svg",
|
IconAsset::ArrowLeft => "icons/arrow_left.svg",
|
||||||
IconAsset::ArrowUpRight => "icons/arrow_up_right.svg",
|
IconAsset::ArrowRight => "icons/arrow_right.svg",
|
||||||
IconAsset::Bolt => "icons/bolt.svg",
|
IconAsset::ArrowUpRight => "icons/arrow_up_right.svg",
|
||||||
IconAsset::Hash => "icons/hash.svg",
|
IconAsset::Bolt => "icons/bolt.svg",
|
||||||
IconAsset::File => "icons/file_icons/file.svg",
|
IconAsset::Hash => "icons/hash.svg",
|
||||||
IconAsset::Folder => "icons/file_icons/folder.svg",
|
IconAsset::ChevronDown => "icons/chevron_down.svg",
|
||||||
IconAsset::FolderOpen => "icons/file_icons/folder_open.svg",
|
IconAsset::ChevronUp => "icons/chevron_up.svg",
|
||||||
|
IconAsset::ChevronLeft => "icons/chevron_left.svg",
|
||||||
|
IconAsset::ChevronRight => "icons/chevron_right.svg",
|
||||||
|
IconAsset::File => "icons/file_icons/file.svg",
|
||||||
|
IconAsset::Folder => "icons/file_icons/folder.svg",
|
||||||
|
IconAsset::FolderOpen => "icons/file_icons/folder_open.svg",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +55,18 @@ pub fn icon(asset: IconAsset) -> Icon {
|
||||||
Icon { asset }
|
Icon { asset }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl Icon {
|
||||||
|
// pub fn new(asset: IconAsset) -> Icon {
|
||||||
|
// Icon { asset }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl Icon {
|
impl Icon {
|
||||||
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
|
||||||
let theme = theme(cx);
|
let theme = theme(cx);
|
||||||
|
|
||||||
svg()
|
svg()
|
||||||
.path(icon_asset(self.asset))
|
.path(self.asset.path())
|
||||||
.size_4()
|
.size_4()
|
||||||
.fill(theme.lowest.base.default.foreground)
|
.fill(theme.lowest.base.default.foreground)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::InteractionState,
|
prelude::{InteractionState, ToggleState},
|
||||||
theme::theme,
|
theme::theme,
|
||||||
ui::{input, label, list_item, IconAsset, LabelColor},
|
ui::{input, label, list_item, IconAsset, LabelColor},
|
||||||
};
|
};
|
||||||
|
@ -44,21 +44,30 @@ impl<V: 'static> ProjectPanel<V> {
|
||||||
div().flex().flex_col().children(
|
div().flex().flex_col().children(
|
||||||
std::iter::repeat_with(|| {
|
std::iter::repeat_with(|| {
|
||||||
vec![
|
vec![
|
||||||
|
list_item(label("sqlez").color(LabelColor::Modified))
|
||||||
|
.left_icon(IconAsset::FolderOpen.into())
|
||||||
|
.indent_level(0.0)
|
||||||
|
.set_toggle(ToggleState::NotToggled),
|
||||||
list_item(label("storybook").color(LabelColor::Modified))
|
list_item(label("storybook").color(LabelColor::Modified))
|
||||||
.left_icon(IconAsset::FolderOpen.into())
|
.left_icon(IconAsset::FolderOpen.into())
|
||||||
.indent_level(0.0),
|
.indent_level(0.0)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
list_item(label("docs").color(LabelColor::Default))
|
list_item(label("docs").color(LabelColor::Default))
|
||||||
.left_icon(IconAsset::Folder.into())
|
.left_icon(IconAsset::Folder.into())
|
||||||
.indent_level(1.0),
|
.indent_level(1.0)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
list_item(label("src").color(LabelColor::Modified))
|
list_item(label("src").color(LabelColor::Modified))
|
||||||
.left_icon(IconAsset::FolderOpen.into())
|
.left_icon(IconAsset::FolderOpen.into())
|
||||||
.indent_level(2.0),
|
.indent_level(2.0)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
list_item(label("ui").color(LabelColor::Modified))
|
list_item(label("ui").color(LabelColor::Modified))
|
||||||
.left_icon(IconAsset::FolderOpen.into())
|
.left_icon(IconAsset::FolderOpen.into())
|
||||||
.indent_level(3.0),
|
.indent_level(3.0)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
list_item(label("component").color(LabelColor::Created))
|
list_item(label("component").color(LabelColor::Created))
|
||||||
.left_icon(IconAsset::FolderOpen.into())
|
.left_icon(IconAsset::FolderOpen.into())
|
||||||
.indent_level(4.0),
|
.indent_level(4.0)
|
||||||
|
.set_toggle(ToggleState::Toggled),
|
||||||
list_item(label("facepile.rs").color(LabelColor::Default))
|
list_item(label("facepile.rs").color(LabelColor::Default))
|
||||||
.left_icon(IconAsset::File.into())
|
.left_icon(IconAsset::File.into())
|
||||||
.indent_level(5.0),
|
.indent_level(5.0),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue