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