diff --git a/crates/ui2/src/components.rs b/crates/ui2/src/components.rs index 438db9b93ab42acc4648bb0e15499393dfd3b444..86fe7bcfb37a9479411574799aaa93460f17176e 100644 --- a/crates/ui2/src/components.rs +++ b/crates/ui2/src/components.rs @@ -4,6 +4,7 @@ mod icon_button; mod list; mod panel; mod project_panel; +mod status_bar; mod workspace; pub use assistant_panel::*; @@ -12,4 +13,5 @@ pub use icon_button::*; pub use list::*; pub use panel::*; pub use project_panel::*; +pub use status_bar::*; pub use workspace::*; diff --git a/crates/ui2/src/components/status_bar.rs b/crates/ui2/src/components/status_bar.rs new file mode 100644 index 0000000000000000000000000000000000000000..cc2cc519f6fc0c71d7f086d351d85942d271aff0 --- /dev/null +++ b/crates/ui2/src/components/status_bar.rs @@ -0,0 +1,145 @@ +use std::marker::PhantomData; + +use crate::prelude::*; +use crate::theme::{theme, Theme}; +use crate::{Icon, IconButton, IconColor, ToolDivider}; + +#[derive(Default, PartialEq)] +pub enum Tool { + #[default] + ProjectPanel, + CollaborationPanel, + Terminal, + Assistant, + Feedback, + Diagnostics, +} + +struct ToolGroup { + active_index: Option, + tools: Vec, +} + +impl Default for ToolGroup { + fn default() -> Self { + ToolGroup { + active_index: None, + tools: vec![], + } + } +} + +#[derive(Element)] +pub struct StatusBar { + state_type: PhantomData, + left_tools: Option, + right_tools: Option, + bottom_tools: Option, +} + +impl StatusBar { + pub fn new() -> Self { + Self { + state_type: PhantomData, + left_tools: None, + right_tools: None, + bottom_tools: None, + } + } + + pub fn left_tool(mut self, tool: Tool, active_index: Option) -> Self { + self.left_tools = { + let mut tools = vec![tool]; + tools.extend(self.left_tools.take().unwrap_or_default().tools); + Some(ToolGroup { + active_index, + tools, + }) + }; + self + } + + pub fn right_tool(mut self, tool: Tool, active_index: Option) -> Self { + self.right_tools = { + let mut tools = vec![tool]; + tools.extend(self.left_tools.take().unwrap_or_default().tools); + Some(ToolGroup { + active_index, + tools, + }) + }; + self + } + + pub fn bottom_tool(mut self, tool: Tool, active_index: Option) -> Self { + self.bottom_tools = { + let mut tools = vec![tool]; + tools.extend(self.left_tools.take().unwrap_or_default().tools); + Some(ToolGroup { + active_index, + tools, + }) + }; + self + } + + fn render(&mut self, cx: &mut ViewContext) -> impl Element { + let theme = theme(cx); + + div() + .py_0p5() + .px_1() + .flex() + .items_center() + .justify_between() + .w_full() + .fill(theme.lowest.base.default.background) + .child(self.left_tools(&theme)) + .child(self.right_tools(&theme)) + } + + fn left_tools(&self, theme: &Theme) -> impl Element { + div() + .flex() + .items_center() + .gap_1() + .child(IconButton::new(Icon::FileTree).color(IconColor::Accent)) + .child(IconButton::new(Icon::Hash)) + .child(ToolDivider::new()) + .child(IconButton::new(Icon::XCircle)) + } + + fn right_tools(&self, theme: &Theme) -> impl Element { + div() + .flex() + .items_center() + .gap_2() + .child( + div() + .flex() + .items_center() + .gap_1() + // .child(Button::new("116:25")) + // .child(Button::new("Rust")), + ) + .child(ToolDivider::new()) + .child( + div() + .flex() + .items_center() + .gap_1() + .child(IconButton::new(Icon::Copilot)) + .child(IconButton::new(Icon::Envelope)), + ) + .child(ToolDivider::new()) + .child( + div() + .flex() + .items_center() + .gap_1() + .child(IconButton::new(Icon::Terminal)) + .child(IconButton::new(Icon::MessageBubbles)) + .child(IconButton::new(Icon::Ai)), + ) + } +} diff --git a/crates/ui2/src/components/workspace.rs b/crates/ui2/src/components/workspace.rs index c384e02678861f27f2831b98075440c0df163e47..fd4ab72101972300c616bc669583fd988543ca43 100644 --- a/crates/ui2/src/components/workspace.rs +++ b/crates/ui2/src/components/workspace.rs @@ -5,7 +5,7 @@ use chrono::DateTime; use gpui3::{relative, rems, Size}; use crate::prelude::*; -use crate::{theme, v_stack, Panel, PanelAllowedSides, PanelSide, ProjectPanel}; +use crate::{theme, v_stack, Panel, PanelAllowedSides, PanelSide, ProjectPanel, StatusBar}; #[derive(Element)] pub struct WorkspaceElement { @@ -185,7 +185,7 @@ impl WorkspaceElement { // .side(PanelSide::Right), // ), ) - // .child(StatusBar::new()) + .child(StatusBar::new()) // An example of a toast is below // Currently because of stacking order this gets obscured by other elements diff --git a/crates/ui2/src/elements.rs b/crates/ui2/src/elements.rs index 9a80eb79cd4dcbf8deed9f84cf4d32789f2b3806..6f9d54e48a555e4da4349b7613c65878b4fa4785 100644 --- a/crates/ui2/src/elements.rs +++ b/crates/ui2/src/elements.rs @@ -4,6 +4,7 @@ mod icon; mod input; mod label; mod stack; +mod tool_divider; pub use avatar::*; pub use button::*; @@ -11,3 +12,4 @@ pub use icon::*; pub use input::*; pub use label::*; pub use stack::*; +pub use tool_divider::*; diff --git a/crates/ui2/src/elements/tool_divider.rs b/crates/ui2/src/elements/tool_divider.rs new file mode 100644 index 0000000000000000000000000000000000000000..96c730c2f61307ebf3a1fe7f51310908f404f91d --- /dev/null +++ b/crates/ui2/src/elements/tool_divider.rs @@ -0,0 +1,23 @@ +use std::marker::PhantomData; + +use crate::prelude::*; +use crate::theme; + +#[derive(Element)] +pub struct ToolDivider { + state_type: PhantomData, +} + +impl ToolDivider { + pub fn new() -> Self { + Self { + state_type: PhantomData, + } + } + + fn render(&mut self, cx: &mut ViewContext) -> impl Element { + let theme = theme(cx); + + div().w_px().h_3().fill(theme.lowest.base.default.border) + } +}