1use std::sync::Arc;
2
3use crate::prelude::*;
4use crate::{Button, Icon, IconButton, IconColor, ToolDivider, Workspace};
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)]
32#[element(view_state = "Workspace")]
33pub struct StatusBar {
34 left_tools: Option<ToolGroup>,
35 right_tools: Option<ToolGroup>,
36 bottom_tools: Option<ToolGroup>,
37}
38
39impl StatusBar {
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(
86 &mut self,
87 view: &mut Workspace,
88 cx: &mut ViewContext<Workspace>,
89 ) -> impl Element<Workspace> {
90 let theme = theme(cx);
91
92 div()
93 .py_0p5()
94 .px_1()
95 .flex()
96 .items_center()
97 .justify_between()
98 .w_full()
99 .bg(theme.status_bar)
100 .child(self.left_tools(view, cx))
101 .child(self.right_tools(view, cx))
102 }
103
104 fn left_tools(&self, workspace: &mut Workspace, cx: &WindowContext) -> impl Element<Workspace> {
105 div()
106 .flex()
107 .items_center()
108 .gap_1()
109 .child(
110 IconButton::<Workspace>::new("project_panel", Icon::FileTree)
111 .when(workspace.is_project_panel_open(), |this| {
112 this.color(IconColor::Accent)
113 })
114 .on_click(|workspace, cx| {
115 workspace.toggle_project_panel(cx);
116 }),
117 )
118 .child(
119 IconButton::<Workspace>::new("collab_panel", Icon::Hash)
120 .when(workspace.is_collab_panel_open(), |this| {
121 this.color(IconColor::Accent)
122 })
123 .on_click(|workspace, cx| {
124 workspace.toggle_collab_panel();
125 }),
126 )
127 .child(ToolDivider::new())
128 .child(IconButton::new("diagnostics", Icon::XCircle))
129 }
130
131 fn right_tools(
132 &self,
133 workspace: &mut Workspace,
134 cx: &WindowContext,
135 ) -> impl Element<Workspace> {
136 div()
137 .flex()
138 .items_center()
139 .gap_2()
140 .child(
141 div()
142 .flex()
143 .items_center()
144 .gap_1()
145 .child(Button::new("116:25"))
146 .child(
147 Button::<Workspace>::new("Rust").on_click(Arc::new(|workspace, cx| {
148 workspace.toggle_language_selector(cx);
149 })),
150 ),
151 )
152 .child(ToolDivider::new())
153 .child(
154 div()
155 .flex()
156 .items_center()
157 .gap_1()
158 .child(
159 IconButton::new("copilot", Icon::Copilot)
160 .on_click(|_, _| println!("Copilot clicked.")),
161 )
162 .child(
163 IconButton::new("envelope", Icon::Envelope)
164 .on_click(|_, _| println!("Send Feedback clicked.")),
165 ),
166 )
167 .child(ToolDivider::new())
168 .child(
169 div()
170 .flex()
171 .items_center()
172 .gap_1()
173 .child(
174 IconButton::<Workspace>::new("terminal", Icon::Terminal)
175 .when(workspace.is_terminal_open(), |this| {
176 this.color(IconColor::Accent)
177 })
178 .on_click(|workspace, cx| {
179 workspace.toggle_terminal(cx);
180 }),
181 )
182 .child(
183 IconButton::<Workspace>::new("chat_panel", Icon::MessageBubbles)
184 .when(workspace.is_chat_panel_open(), |this| {
185 this.color(IconColor::Accent)
186 })
187 .on_click(|workspace, cx| {
188 workspace.toggle_chat_panel(cx);
189 }),
190 )
191 .child(
192 IconButton::<Workspace>::new("assistant_panel", Icon::Ai)
193 .when(workspace.is_assistant_panel_open(), |this| {
194 this.color(IconColor::Accent)
195 })
196 .on_click(|workspace, cx| {
197 workspace.toggle_assistant_panel(cx);
198 }),
199 ),
200 )
201 }
202}