status_bar.rs

  1use std::marker::PhantomData;
  2
  3use crate::prelude::*;
  4use crate::theme::{theme, Theme};
  5use crate::{Button, Icon, IconButton, IconColor, ToolDivider};
  6
  7#[derive(Default, PartialEq)]
  8pub enum Tool {
  9    #[default]
 10    ProjectPanel,
 11    CollaborationPanel,
 12    Terminal,
 13    Assistant,
 14    Feedback,
 15    Diagnostics,
 16}
 17
 18struct ToolGroup {
 19    active_index: Option<usize>,
 20    tools: Vec<Tool>,
 21}
 22
 23impl Default for ToolGroup {
 24    fn default() -> Self {
 25        ToolGroup {
 26            active_index: None,
 27            tools: vec![],
 28        }
 29    }
 30}
 31
 32#[derive(Element)]
 33pub struct StatusBar<V: 'static> {
 34    view_type: PhantomData<V>,
 35    left_tools: Option<ToolGroup>,
 36    right_tools: Option<ToolGroup>,
 37    bottom_tools: Option<ToolGroup>,
 38}
 39
 40impl<V: 'static> StatusBar<V> {
 41    pub fn new() -> Self {
 42        Self {
 43            view_type: PhantomData,
 44            left_tools: None,
 45            right_tools: None,
 46            bottom_tools: None,
 47        }
 48    }
 49
 50    pub fn left_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 51        self.left_tools = {
 52            let mut tools = vec![tool];
 53            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 54            Some(ToolGroup {
 55                active_index,
 56                tools,
 57            })
 58        };
 59        self
 60    }
 61
 62    pub fn right_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 63        self.right_tools = {
 64            let mut tools = vec![tool];
 65            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 66            Some(ToolGroup {
 67                active_index,
 68                tools,
 69            })
 70        };
 71        self
 72    }
 73
 74    pub fn bottom_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 75        self.bottom_tools = {
 76            let mut tools = vec![tool];
 77            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 78            Some(ToolGroup {
 79                active_index,
 80                tools,
 81            })
 82        };
 83        self
 84    }
 85
 86    fn render(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
 87        let theme = theme(cx);
 88
 89        div()
 90            .py_0p5()
 91            .px_1()
 92            .flex()
 93            .items_center()
 94            .justify_between()
 95            .w_full()
 96            .fill(theme.lowest.base.default.background)
 97            .child(self.left_tools(&theme))
 98            .child(self.right_tools(&theme))
 99    }
100
101    fn left_tools(&self, theme: &Theme) -> impl Element<V> {
102        div()
103            .flex()
104            .items_center()
105            .gap_1()
106            .child(IconButton::new(Icon::FileTree).color(IconColor::Accent))
107            .child(IconButton::new(Icon::Hash))
108            .child(ToolDivider::new())
109            .child(IconButton::new(Icon::XCircle))
110    }
111    fn right_tools(&self, theme: &Theme) -> impl Element<V> {
112        div()
113            .flex()
114            .items_center()
115            .gap_2()
116            .child(
117                div()
118                    .flex()
119                    .items_center()
120                    .gap_1()
121                    .child(Button::new("116:25"))
122                    .child(Button::new("Rust")),
123            )
124            .child(ToolDivider::new())
125            .child(
126                div()
127                    .flex()
128                    .items_center()
129                    .gap_1()
130                    .child(IconButton::new(Icon::Copilot))
131                    .child(IconButton::new(Icon::Envelope)),
132            )
133            .child(ToolDivider::new())
134            .child(
135                div()
136                    .flex()
137                    .items_center()
138                    .gap_1()
139                    .child(IconButton::new(Icon::Terminal))
140                    .child(IconButton::new(Icon::MessageBubbles))
141                    .child(IconButton::new(Icon::Ai)),
142            )
143    }
144}