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(Component)]
32#[component(view_type = "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 left_tools: None,
43 right_tools: None,
44 bottom_tools: None,
45 }
46 }
47
48 pub fn left_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
49 self.left_tools = {
50 let mut tools = vec![tool];
51 tools.extend(self.left_tools.take().unwrap_or_default().tools);
52 Some(ToolGroup {
53 active_index,
54 tools,
55 })
56 };
57 self
58 }
59
60 pub fn right_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
61 self.right_tools = {
62 let mut tools = vec![tool];
63 tools.extend(self.left_tools.take().unwrap_or_default().tools);
64 Some(ToolGroup {
65 active_index,
66 tools,
67 })
68 };
69 self
70 }
71
72 pub fn bottom_tool(mut self, tool: Tool, active_index: Option<usize>) -> Self {
73 self.bottom_tools = {
74 let mut tools = vec![tool];
75 tools.extend(self.left_tools.take().unwrap_or_default().tools);
76 Some(ToolGroup {
77 active_index,
78 tools,
79 })
80 };
81 self
82 }
83
84 fn render(
85 self,
86 view: &mut Workspace,
87 cx: &mut ViewContext<Workspace>,
88 ) -> impl Component<Workspace> {
89 div()
90 .py_0p5()
91 .px_1()
92 .flex()
93 .items_center()
94 .justify_between()
95 .w_full()
96 .bg(cx.theme().colors().status_bar)
97 .child(self.left_tools(view, cx))
98 .child(self.right_tools(view, cx))
99 }
100
101 fn left_tools(
102 &self,
103 workspace: &mut Workspace,
104 cx: &WindowContext,
105 ) -> impl Component<Workspace> {
106 div()
107 .flex()
108 .items_center()
109 .gap_1()
110 .child(
111 IconButton::<Workspace>::new("project_panel", Icon::FileTree)
112 .when(workspace.is_project_panel_open(), |this| {
113 this.color(IconColor::Accent)
114 })
115 .on_click(|workspace, cx| {
116 workspace.toggle_project_panel(cx);
117 }),
118 )
119 .child(
120 IconButton::<Workspace>::new("collab_panel", Icon::Hash)
121 .when(workspace.is_collab_panel_open(), |this| {
122 this.color(IconColor::Accent)
123 })
124 .on_click(|workspace, cx| {
125 workspace.toggle_collab_panel();
126 }),
127 )
128 .child(ToolDivider::new())
129 .child(IconButton::new("diagnostics", Icon::XCircle))
130 }
131
132 fn right_tools(
133 &self,
134 workspace: &mut Workspace,
135 cx: &WindowContext,
136 ) -> impl Component<Workspace> {
137 div()
138 .flex()
139 .items_center()
140 .gap_2()
141 .child(
142 div()
143 .flex()
144 .items_center()
145 .gap_1()
146 .child(Button::new("116:25"))
147 .child(
148 Button::<Workspace>::new("Rust").on_click(Arc::new(|workspace, cx| {
149 workspace.toggle_language_selector(cx);
150 })),
151 ),
152 )
153 .child(ToolDivider::new())
154 .child(
155 div()
156 .flex()
157 .items_center()
158 .gap_1()
159 .child(
160 IconButton::new("copilot", Icon::Copilot)
161 .on_click(|_, _| println!("Copilot clicked.")),
162 )
163 .child(
164 IconButton::new("envelope", Icon::Envelope)
165 .on_click(|_, _| println!("Send Feedback clicked.")),
166 ),
167 )
168 .child(ToolDivider::new())
169 .child(
170 div()
171 .flex()
172 .items_center()
173 .gap_1()
174 .child(
175 IconButton::<Workspace>::new("terminal", Icon::Terminal)
176 .when(workspace.is_terminal_open(), |this| {
177 this.color(IconColor::Accent)
178 })
179 .on_click(|workspace, cx| {
180 workspace.toggle_terminal(cx);
181 }),
182 )
183 .child(
184 IconButton::<Workspace>::new("chat_panel", Icon::MessageBubbles)
185 .when(workspace.is_chat_panel_open(), |this| {
186 this.color(IconColor::Accent)
187 })
188 .on_click(|workspace, cx| {
189 workspace.toggle_chat_panel(cx);
190 }),
191 )
192 .child(
193 IconButton::<Workspace>::new("assistant_panel", Icon::Ai)
194 .when(workspace.is_assistant_panel_open(), |this| {
195 this.color(IconColor::Accent)
196 })
197 .on_click(|workspace, cx| {
198 workspace.toggle_assistant_panel(cx);
199 }),
200 ),
201 )
202 }
203}