workspace.rs

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