status_bar.rs

  1use std::marker::PhantomData;
  2
  3use crate::prelude::*;
  4use crate::{Button, ClickHandler, 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    on_select_language: ClickHandler<S>,
 38}
 39
 40impl<S: 'static + Send + Sync + Clone> StatusBar<S> {
 41    pub fn new(on_select_language: ClickHandler<S>) -> Self {
 42        Self {
 43            state_type: PhantomData,
 44            left_tools: None,
 45            right_tools: None,
 46            bottom_tools: None,
 47            on_select_language,
 48        }
 49    }
 50
 51    pub fn left_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 52        self.left_tools = {
 53            let mut tools = vec![tool];
 54            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 55            Some(ToolGroup {
 56                active_index,
 57                tools,
 58            })
 59        };
 60        self
 61    }
 62
 63    pub fn right_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 64        self.right_tools = {
 65            let mut tools = vec![tool];
 66            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 67            Some(ToolGroup {
 68                active_index,
 69                tools,
 70            })
 71        };
 72        self
 73    }
 74
 75    pub fn bottom_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
 76        self.bottom_tools = {
 77            let mut tools = vec![tool];
 78            tools.extend(self.left_tools.take().unwrap_or_default().tools);
 79            Some(ToolGroup {
 80                active_index,
 81                tools,
 82            })
 83        };
 84        self
 85    }
 86
 87    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
 88        let theme = theme(cx);
 89
 90        div()
 91            .py_0p5()
 92            .px_1()
 93            .flex()
 94            .items_center()
 95            .justify_between()
 96            .w_full()
 97            .fill(theme.lowest.base.default.background)
 98            .child(self.left_tools(&theme))
 99            .child(self.right_tools(&theme))
100    }
101
102    fn left_tools(&self, theme: &Theme) -> impl Element<State = S> {
103        div()
104            .flex()
105            .items_center()
106            .gap_1()
107            .child(IconButton::new(Icon::FileTree).color(IconColor::Accent))
108            .child(IconButton::new(Icon::Hash))
109            .child(ToolDivider::new())
110            .child(IconButton::new(Icon::XCircle))
111    }
112
113    fn right_tools(&self, theme: &Theme) -> impl Element<State = S> {
114        div()
115            .flex()
116            .items_center()
117            .gap_2()
118            .child(
119                div()
120                    .flex()
121                    .items_center()
122                    .gap_1()
123                    .child(Button::new("116:25"))
124                    .child(Button::new("Rust").on_click(self.on_select_language.clone())),
125            )
126            .child(ToolDivider::new())
127            .child(
128                div()
129                    .flex()
130                    .items_center()
131                    .gap_1()
132                    .child(
133                        IconButton::new(Icon::Copilot)
134                            .on_click(|_, _| println!("Copilot clicked.")),
135                    )
136                    .child(
137                        IconButton::new(Icon::Envelope)
138                            .on_click(|_, _| println!("Send Feedback clicked.")),
139                    ),
140            )
141            .child(ToolDivider::new())
142            .child(
143                div()
144                    .flex()
145                    .items_center()
146                    .gap_1()
147                    .child(IconButton::new(Icon::Terminal))
148                    .child(
149                        IconButton::new(Icon::MessageBubbles)
150                            .on_click(|_, _| println!("Chat Panel clicked.")),
151                    )
152                    .child(IconButton::new(Icon::Ai)),
153            )
154    }
155}