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}