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}