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 .size_full()
86 .flex()
87 .flex_col()
88 .font("Zed Sans Extended")
89 .gap_0()
90 .justify_start()
91 .items_start()
92 .text_color(theme.lowest.base.default.foreground)
93 .fill(theme.lowest.base.default.background)
94 .child(TitleBar::new(cx).set_livestream(Some(Livestream {
95 players: random_players_with_call_status(7),
96 channel: Some("gpui2-ui".to_string()),
97 })))
98 .child(
99 div()
100 .flex_1()
101 .w_full()
102 .flex()
103 .flex_row()
104 .overflow_hidden()
105 .border_t()
106 .border_b()
107 .border_color(theme.lowest.base.default.border)
108 .child(
109 Panel::new(
110 self.left_panel_scroll_state.clone(),
111 |_, payload| vec![ProjectPanel::new(ScrollState::default()).into_any()],
112 Box::new(()),
113 )
114 .side(PanelSide::Left),
115 )
116 .child(
117 v_stack()
118 .flex_1()
119 .h_full()
120 .child(
121 div()
122 .flex()
123 .flex_1()
124 // CSS Hack: Flex 1 has to have a set height to properly fill the space
125 // Or it will give you a height of 0
126 .h_px()
127 .child(root_group),
128 )
129 .child(
130 Panel::new(
131 self.bottom_panel_scroll_state.clone(),
132 |_, _| vec![Terminal::new().into_any()],
133 Box::new(()),
134 )
135 .allowed_sides(PanelAllowedSides::BottomOnly)
136 .side(PanelSide::Bottom),
137 ),
138 )
139 .child(
140 Panel::new(
141 self.right_panel_scroll_state.clone(),
142 |_, payload| {
143 vec![ChatPanel::new(ScrollState::default())
144 .with_messages(vec![
145 ChatMessage::new(
146 "osiewicz".to_string(),
147 "is this thing on?".to_string(),
148 DateTime::parse_from_rfc3339(
149 "2023-09-27T15:40:52.707Z",
150 )
151 .unwrap()
152 .naive_local(),
153 ),
154 ChatMessage::new(
155 "maxdeviant".to_string(),
156 "Reading you loud and clear!".to_string(),
157 DateTime::parse_from_rfc3339(
158 "2023-09-28T15:40:52.707Z",
159 )
160 .unwrap()
161 .naive_local(),
162 ),
163 ])
164 .into_any()]
165 },
166 Box::new(()),
167 )
168 .side(PanelSide::Right),
169 ),
170 )
171 .child(StatusBar::new())
172 }
173}