terminal.rs

  1use std::marker::PhantomData;
  2use std::sync::Arc;
  3
  4use gpui3::{relative, rems, Size};
  5
  6use crate::prelude::*;
  7use crate::{theme, Icon, IconButton, Pane, Tab};
  8
  9#[derive(Element)]
 10pub struct Terminal<S: 'static + Send + Sync + Clone> {
 11    state_type: PhantomData<S>,
 12}
 13
 14impl<S: 'static + Send + Sync + Clone> Terminal<S> {
 15    pub fn new() -> Self {
 16        Self {
 17            state_type: PhantomData,
 18        }
 19    }
 20
 21    fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
 22        let theme = theme(cx);
 23
 24        let can_navigate_back = true;
 25        let can_navigate_forward = false;
 26
 27        div()
 28            .flex()
 29            .flex_col()
 30            .w_full()
 31            .child(
 32                // Terminal Tabs.
 33                div()
 34                    .w_full()
 35                    .flex()
 36                    .fill(theme.middle.base.default.background)
 37                    .child(
 38                        div().px_1().flex().flex_none().gap_2().child(
 39                            div()
 40                                .flex()
 41                                .items_center()
 42                                .gap_px()
 43                                .child(
 44                                    IconButton::new(Icon::ArrowLeft).state(
 45                                        InteractionState::Enabled.if_enabled(can_navigate_back),
 46                                    ),
 47                                )
 48                                .child(IconButton::new(Icon::ArrowRight).state(
 49                                    InteractionState::Enabled.if_enabled(can_navigate_forward),
 50                                )),
 51                        ),
 52                    )
 53                    .child(
 54                        div().w_0().flex_1().h_full().child(
 55                            div()
 56                                .flex()
 57                                .child(
 58                                    Tab::new()
 59                                        .title("zed — fish".to_string())
 60                                        .icon(Icon::Terminal)
 61                                        .close_side(IconSide::Right)
 62                                        .current(true),
 63                                )
 64                                .child(
 65                                    Tab::new()
 66                                        .title("zed — fish".to_string())
 67                                        .icon(Icon::Terminal)
 68                                        .close_side(IconSide::Right)
 69                                        .current(false),
 70                                ),
 71                        ),
 72                    ),
 73            )
 74            // Terminal Pane.
 75            .child(Pane::new(
 76                ScrollState::default(),
 77                Size {
 78                    width: relative(1.).into(),
 79                    height: rems(36.).into(),
 80                },
 81                |_, payload| {
 82                    let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
 83
 84                    vec![crate::static_data::terminal_buffer(&theme).into_any()]
 85                },
 86                Box::new(theme),
 87            ))
 88    }
 89}
 90
 91#[cfg(feature = "stories")]
 92pub use stories::*;
 93
 94#[cfg(feature = "stories")]
 95mod stories {
 96    use crate::Story;
 97
 98    use super::*;
 99
100    #[derive(Element)]
101    pub struct TerminalStory<S: 'static + Send + Sync + Clone> {
102        state_type: PhantomData<S>,
103    }
104
105    impl<S: 'static + Send + Sync + Clone> TerminalStory<S> {
106        pub fn new() -> Self {
107            Self {
108                state_type: PhantomData,
109            }
110        }
111
112        fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
113            Story::container(cx)
114                .child(Story::title_for::<_, Terminal<S>>(cx))
115                .child(Story::label(cx, "Default"))
116                .child(Terminal::new())
117        }
118    }
119}