workspace.rs

  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}