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}