status_bar.rs

  1use std::marker::PhantomData;
  2
  3use crate::prelude::*;
  4use crate::{Button, Icon, IconButton, IconColor, ToolDivider};
  5
  6#[derive(Default, PartialEq)]
  7pub enum Tool {
  8    #[default]
  9    ProjectPanel,
 10    CollaborationPanel,
 11    Terminal,
 12    Assistant,
 13    Feedback,
 14    Diagnostics,
 15}
 16
 17struct ToolGroup {
 18    active_index: Option<usize>,
 19    tools: Vec<Tool>,
 20}
 21
 22impl Default for ToolGroup {
 23    fn default() -> Self {
 24        ToolGroup {
 25            active_index: None,
 26            tools: vec![],
 27        }
 28    }
 29}
 30
 31#[derive(Element)]
 32pub struct StatusBar<S: 'static + Send + Sync + Clone> {
 33    state_type: PhantomData<S>,
 34    left_tools: Option<ToolGroup>,
 35    right_tools: Option<ToolGroup>,
 36    bottom_tools: Option<ToolGroup>,
 37}
 38
 39impl<S: 'static + Send + Sync + Clone> StatusBar<S> {
 40    pub fn new() -> Self {
 41        Self {
 42            state_type: PhantomData,
 43            left_tools: None,
 44            right_tools: None,
 45            bottom_tools: None,
 46        }
 47    }
 48
 49    pub fn left_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 50        self.left_tools = {
 51            let mut tools = vec![tool];
 52            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 53            Some(ToolGroup {
 54                active_index,
 55                tools,
 56            })
 57        };
 58        self
 59    }
 60
 61    pub fn right_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 62        self.right_tools = {
 63            let mut tools = vec![tool];
 64            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 65            Some(ToolGroup {
 66                active_index,
 67                tools,
 68            })
 69        };
 70        self
 71    }
 72
 73    pub fn bottom_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 74        self.bottom_tools = {
 75            let mut tools = vec![tool];
 76            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 77            Some(ToolGroup {
 78                active_index,
 79                tools,
 80            })
 81        };
 82        self
 83    }
 84
 85    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
 86        let theme = theme(cx);
 87
 88        div()
 89            .py_0p5()
 90            .px_1()
 91            .flex()
 92            .items_center()
 93            .justify_between()
 94            .w_full()
 95            .fill(theme.lowest.base.default.background)
 96            .child(self.left_tools(&theme))
 97            .child(self.right_tools(&theme))
 98    }
 99
100    fn left_tools(&self, theme: &Theme) -> impl Element<State = S> {
101        div()
102            .flex()
103            .items_center()
104            .gap_1()
105            .child(IconButton::new(Icon::FileTree).color(IconColor::Accent))
106            .child(IconButton::new(Icon::Hash))
107            .child(ToolDivider::new())
108            .child(IconButton::new(Icon::XCircle))
109    }
110
111    fn right_tools(&self, theme: &Theme) -> impl Element<State = S> {
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}