1use std::marker::PhantomData;
2use std::sync::Arc;
3
4use chrono::DateTime;
5use gpui3::{relative, rems, Size};
6
7use crate::{prelude::*, Pane, PaneGroup, SplitDirection};
8use crate::{theme, v_stack, Panel, PanelAllowedSides, PanelSide, ProjectPanel, StatusBar};
9
10#[derive(Element)]
11pub struct WorkspaceElement<S: 'static + Send + Sync + Clone> {
12 state_type: PhantomData<S>,
13 left_panel_scroll_state: ScrollState,
14 right_panel_scroll_state: ScrollState,
15 tab_bar_scroll_state: ScrollState,
16 bottom_panel_scroll_state: ScrollState,
17}
18
19impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
20 pub fn new() -> Self {
21 Self {
22 state_type: PhantomData,
23 left_panel_scroll_state: ScrollState::default(),
24 right_panel_scroll_state: ScrollState::default(),
25 tab_bar_scroll_state: ScrollState::default(),
26 bottom_panel_scroll_state: ScrollState::default(),
27 }
28 }
29
30 pub fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
31 let theme = theme(cx).clone();
32
33 let temp_size = rems(36.).into();
34
35 let root_group = PaneGroup::new_groups(
36 vec![
37 PaneGroup::new_panes(
38 vec![
39 Pane::new(
40 ScrollState::default(),
41 Size {
42 width: relative(1.).into(),
43 height: temp_size,
44 },
45 |_, payload| {
46 let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
47
48 vec![
49 div()
50 .w_full()
51 .fill(gpui3::rgb::<gpui3::Hsla>(0xff0000))
52 .into_any(), // EditorPane::new(hello_world_rust_editor_with_status_example(
53 // &theme,
54 // ))
55 // .into_any()
56 ]
57 },
58 Box::new(theme.clone()),
59 ),
60 Pane::new(
61 ScrollState::default(),
62 Size {
63 width: relative(1.).into(),
64 height: temp_size,
65 },
66 |_, _| {
67 vec![
68 div()
69 .w_full()
70 .fill(gpui3::rgb::<gpui3::Hsla>(0x00ff00))
71 .into_any(),
72 // Terminal::new().into_any()
73 ]
74 },
75 Box::new(()),
76 ),
77 ],
78 SplitDirection::Vertical,
79 ),
80 PaneGroup::new_panes(
81 vec![Pane::new(
82 ScrollState::default(),
83 Size {
84 width: relative(1.).into(),
85 height: relative(1.).into(),
86 },
87 |_, payload| {
88 let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
89
90 vec![
91 div()
92 .w_full()
93 .fill(gpui3::rgb::<gpui3::Hsla>(0x0000ff))
94 .into_any(),
95 // EditorPane::new(hello_world_rust_editor_with_status_example(
96 // &theme,
97 // ))
98 // .into_any()
99 ]
100 },
101 Box::new(theme.clone()),
102 )],
103 SplitDirection::Vertical,
104 ),
105 ],
106 SplitDirection::Horizontal,
107 );
108
109 div()
110 .relative()
111 .size_full()
112 .flex()
113 .flex_col()
114 .font("Zed Sans Extended")
115 .gap_0()
116 .justify_start()
117 .items_start()
118 .text_color(theme.lowest.base.default.foreground)
119 .fill(theme.lowest.base.default.background)
120 // .child(TitleBar::new(cx).set_livestream(Some(Livestream {
121 // players: random_players_with_call_status(7),
122 // channel: Some("gpui2-ui".to_string()),
123 // })))
124 .child(
125 div()
126 .flex_1()
127 .w_full()
128 .flex()
129 .flex_row()
130 .overflow_hidden()
131 .border_t()
132 .border_b()
133 .border_color(theme.lowest.base.default.border)
134 .child(
135 Panel::new(
136 self.left_panel_scroll_state.clone(),
137 |_, payload| vec![ProjectPanel::new(ScrollState::default()).into_any()],
138 Box::new(()),
139 )
140 .side(PanelSide::Left),
141 )
142 .child(
143 v_stack()
144 .flex_1()
145 .h_full()
146 .child(
147 div()
148 .flex()
149 .flex_1()
150 // CSS Hack: Flex 1 has to have a set height to properly fill the space
151 // Or it will give you a height of 0
152 .h_px()
153 .child(root_group),
154 )
155 .child(
156 Panel::new(
157 self.bottom_panel_scroll_state.clone(),
158 |_, _| {
159 vec![
160 // Terminal::new().into_any()
161 ]
162 },
163 Box::new(()),
164 )
165 .allowed_sides(PanelAllowedSides::BottomOnly)
166 .side(PanelSide::Bottom),
167 ),
168 )
169 .child(
170 Panel::new(
171 self.right_panel_scroll_state.clone(),
172 |_, payload| vec![ProjectPanel::new(ScrollState::default()).into_any()],
173 Box::new(()),
174 )
175 .side(PanelSide::Right),
176 ),
177 // .child(
178 // Panel::new(
179 // self.right_panel_scroll_state.clone(),
180 // |_, payload| {
181 // vec![ChatPanel::new(ScrollState::default())
182 // .with_messages(vec![
183 // ChatMessage::new(
184 // "osiewicz".to_string(),
185 // "is this thing on?".to_string(),
186 // DateTime::parse_from_rfc3339(
187 // "2023-09-27T15:40:52.707Z",
188 // )
189 // .unwrap()
190 // .naive_local(),
191 // ),
192 // ChatMessage::new(
193 // "maxdeviant".to_string(),
194 // "Reading you loud and clear!".to_string(),
195 // DateTime::parse_from_rfc3339(
196 // "2023-09-28T15:40:52.707Z",
197 // )
198 // .unwrap()
199 // .naive_local(),
200 // ),
201 // ])
202 // .into_any()]
203 // },
204 // Box::new(()),
205 // )
206 // .side(PanelSide::Right),
207 // ),
208 )
209 .child(StatusBar::new())
210 // An example of a toast is below
211 // Currently because of stacking order this gets obscured by other elements
212
213 // .child(Toast::new(
214 // ToastOrigin::Bottom,
215 // |_, payload| {
216 // let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
217
218 // vec![Label::new("label").into_any()]
219 // },
220 // Box::new(theme.clone()),
221 // ))
222 }
223}