terminal.rs

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