Add icon, list_item, work on project panel

This commit is contained in:
Nate Butler 2023-09-19 00:25:46 -04:00
parent 2701be91e3
commit 8aa4fbea83
8 changed files with 160 additions and 25 deletions

View file

@ -1,21 +1,22 @@
mod component;
mod element;
mod module;
pub use component::facepile::*;
pub use component::follow_group::*;
pub use component::tab::*;
pub use module::chat_panel::*;
pub use module::project_panel::*;
pub use module::status_bar::*;
pub use module::tab_bar::*;
pub use module::title_bar::*;
pub use element::avatar::*;
pub use element::icon::*;
pub use element::icon_button::*;
pub use element::indicator::*;
pub use element::input::*;
pub use element::label::*;
pub use element::text_button::*;
pub use element::tool_divider::*;
mod component;
pub use component::facepile::*;
pub use component::follow_group::*;
pub use component::list_item::*;
pub use component::tab::*;
mod module;
pub use module::chat_panel::*;
pub use module::project_panel::*;
pub use module::status_bar::*;
pub use module::tab_bar::*;
pub use module::title_bar::*;

View file

@ -1,3 +1,4 @@
pub(crate) mod facepile;
pub(crate) mod follow_group;
pub(crate) mod list_item;
pub(crate) mod tab;

View file

@ -0,0 +1,57 @@
use crate::prelude::InteractionState;
use crate::theme::theme;
use crate::ui::{icon, IconAsset, Label};
use gpui2::geometry::rems;
use gpui2::style::StyleHelpers;
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ParentElement, ViewContext};
#[derive(Element)]
pub struct ListItem {
label: Label,
left_icon: Option<IconAsset>,
indent_level: f32,
state: InteractionState,
}
pub fn list_item(label: Label) -> ListItem {
ListItem {
label,
indent_level: 0.0,
left_icon: None,
state: InteractionState::default(),
}
}
impl ListItem {
pub fn indent_level(mut self, indent_level: f32) -> Self {
self.indent_level = indent_level;
self
}
pub fn left_icon(mut self, left_icon: Option<IconAsset>) -> Self {
self.left_icon = left_icon;
self
}
pub fn state(mut self, state: InteractionState) -> Self {
self.state = state;
self
}
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
let mut el = div()
.h_7()
.px_2()
.ml(rems(0.75 * self.indent_level.clone()))
.flex()
.gap_2()
.items_center();
if self.left_icon.is_some() {
el = el.child(icon(self.left_icon.clone().unwrap()))
}
el.child(self.label.clone())
}
}

View file

@ -1,4 +1,5 @@
pub(crate) mod avatar;
pub(crate) mod icon;
pub(crate) mod icon_button;
pub(crate) mod indicator;
pub(crate) mod input;

View file

@ -5,8 +5,6 @@ use gpui2::style::StyleHelpers;
use gpui2::{ArcCow, IntoElement};
use gpui2::{Element, ViewContext};
pub type UnknownString = ArcCow<'static, str>;
#[derive(Element, Clone)]
pub struct Avatar {
src: ArcCow<'static, str>,

View file

@ -0,0 +1,55 @@
use std::borrow::Cow;
use crate::theme::theme;
use gpui2::elements::svg;
use gpui2::style::StyleHelpers;
use gpui2::IntoElement;
use gpui2::{Element, ViewContext};
#[derive(Default, PartialEq, Copy, Clone)]
pub enum IconAsset {
Ai,
ArrowLeft,
ArrowRight,
#[default]
ArrowUpRight,
Bolt,
Hash,
File,
Folder,
FolderOpen,
}
pub fn icon_asset(asset: IconAsset) -> impl Into<Cow<'static, str>> {
match asset {
IconAsset::Ai => "icons/ai.svg",
IconAsset::ArrowLeft => "icons/arrow_left.svg",
IconAsset::ArrowRight => "icons/arrow_right.svg",
IconAsset::ArrowUpRight => "icons/arrow_up_right.svg",
IconAsset::Bolt => "icons/bolt.svg",
IconAsset::Hash => "icons/hash.svg",
IconAsset::File => "icons/file_icons/file.svg",
IconAsset::Folder => "icons/file_icons/folder.svg",
IconAsset::FolderOpen => "icons/file_icons/folder_open.svg",
}
}
#[derive(Element, Clone)]
pub struct Icon {
asset: IconAsset,
}
pub fn icon(asset: IconAsset) -> Icon {
Icon { asset }
}
impl Icon {
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
svg()
.path(icon_asset(self.asset))
.size_4()
.fill(theme.lowest.base.default.foreground)
}
}

View file

@ -22,7 +22,7 @@ pub struct Label {
pub fn label(label: &'static str) -> Label {
Label {
label: "Label",
label,
color: LabelColor::Default,
}
}

View file

@ -1,7 +1,7 @@
use crate::{
prelude::InteractionState,
theme::theme,
ui::{input, label, LabelColor},
ui::{input, label, list_item, IconAsset, LabelColor},
};
use gpui2::{
elements::{div, div::ScrollState},
@ -29,7 +29,7 @@ impl<V: 'static> ProjectPanel<V> {
let theme = theme(cx);
div()
.w_64()
.w_56()
.h_full()
.flex()
.flex_col()
@ -41,17 +41,39 @@ impl<V: 'static> ProjectPanel<V> {
.flex_col()
.overflow_y_scroll(self.scroll_state.clone())
.child(
div().py_2().flex().flex_col().children(
div().flex().flex_col().children(
std::iter::repeat_with(|| {
vec![
label("File"),
label("Modified File").color(LabelColor::Modified),
label("Created File").color(LabelColor::Created),
label("Deleted File").color(LabelColor::Deleted),
label("Hidden File").color(LabelColor::Hidden),
list_item(label("storybook").color(LabelColor::Modified))
.left_icon(IconAsset::FolderOpen.into())
.indent_level(0.0),
list_item(label("docs").color(LabelColor::Default))
.left_icon(IconAsset::Folder.into())
.indent_level(1.0),
list_item(label("src").color(LabelColor::Modified))
.left_icon(IconAsset::FolderOpen.into())
.indent_level(2.0),
list_item(label("ui").color(LabelColor::Modified))
.left_icon(IconAsset::FolderOpen.into())
.indent_level(3.0),
list_item(label("component").color(LabelColor::Created))
.left_icon(IconAsset::FolderOpen.into())
.indent_level(4.0),
list_item(label("facepile.rs").color(LabelColor::Default))
.left_icon(IconAsset::File.into())
.indent_level(5.0),
list_item(label("follow_group.rs").color(LabelColor::Default))
.left_icon(IconAsset::File.into())
.indent_level(5.0),
list_item(label("list_item.rs").color(LabelColor::Created))
.left_icon(IconAsset::File.into())
.indent_level(5.0),
list_item(label("tab.rs").color(LabelColor::Default))
.left_icon(IconAsset::File.into())
.indent_level(5.0),
]
})
.take(60)
.take(10)
.flatten(),
),
),