Add StatusBar component

This commit is contained in:
Marshall Bowers 2023-10-06 18:25:55 -04:00
parent 28d504d7d3
commit b53579858a
5 changed files with 174 additions and 2 deletions

View file

@ -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::*;

View file

@ -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<usize>,
tools: Vec<Tool>,
}
impl Default for ToolGroup {
fn default() -> Self {
ToolGroup {
active_index: None,
tools: vec![],
}
}
}
#[derive(Element)]
pub struct StatusBar<S: 'static + Send + Sync> {
state_type: PhantomData<S>,
left_tools: Option<ToolGroup>,
right_tools: Option<ToolGroup>,
bottom_tools: Option<ToolGroup>,
}
impl<S: 'static + Send + Sync> StatusBar<S> {
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<usize>) -> 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<usize>) -> 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<usize>) -> 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<S>) -> impl Element<State = S> {
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<State = S> {
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<State = S> {
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)),
)
}
}

View file

@ -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<S: 'static + Send + Sync + Clone> {
@ -185,7 +185,7 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
// .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

View file

@ -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::*;

View file

@ -0,0 +1,23 @@
use std::marker::PhantomData;
use crate::prelude::*;
use crate::theme;
#[derive(Element)]
pub struct ToolDivider<S: 'static + Send + Sync> {
state_type: PhantomData<S>,
}
impl<S: 'static + Send + Sync> ToolDivider<S> {
pub fn new() -> Self {
Self {
state_type: PhantomData,
}
}
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
let theme = theme(cx);
div().w_px().h_3().fill(theme.lowest.base.default.border)
}
}