1use crate::prelude::*;
2use crate::{Icon, IconButton, Pane, Tab};
3use gpui::{relative, rems, Div, RenderOnce, Size};
4
5#[derive(RenderOnce)]
6pub struct Terminal;
7
8impl<V: 'static> Component<V> for Terminal {
9 type Rendered = Div<V>;
10
11 fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
12 let can_navigate_back = true;
13 let can_navigate_forward = false;
14
15 div()
16 .flex()
17 .flex_col()
18 .w_full()
19 .child(
20 // Terminal Tabs.
21 div()
22 .w_full()
23 .flex()
24 .bg(cx.theme().colors().surface_background)
25 .child(
26 div().px_1().flex().flex_none().gap_2().child(
27 div()
28 .flex()
29 .items_center()
30 .gap_px()
31 .child(
32 IconButton::new("arrow_left", Icon::ArrowLeft).state(
33 InteractionState::Enabled.if_enabled(can_navigate_back),
34 ),
35 )
36 .child(IconButton::new("arrow_right", Icon::ArrowRight).state(
37 InteractionState::Enabled.if_enabled(can_navigate_forward),
38 )),
39 ),
40 )
41 .child(
42 div().w_0().flex_1().h_full().child(
43 div()
44 .flex()
45 .child(
46 Tab::new(1)
47 .title("zed — fish".to_string())
48 .icon(Icon::Terminal)
49 .close_side(IconSide::Right)
50 .current(true),
51 )
52 .child(
53 Tab::new(2)
54 .title("zed — fish".to_string())
55 .icon(Icon::Terminal)
56 .close_side(IconSide::Right)
57 .current(false),
58 ),
59 ),
60 ),
61 )
62 // Terminal Pane.
63 .child(
64 Pane::new(
65 "terminal",
66 Size {
67 width: relative(1.).into(),
68 height: rems(36.).into(),
69 },
70 )
71 .child(crate::static_data::terminal_buffer(cx)),
72 )
73 }
74}
75
76impl Terminal {
77 pub fn new() -> Self {
78 Self
79 }
80
81 fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
82 let can_navigate_back = true;
83 let can_navigate_forward = false;
84
85 div()
86 .flex()
87 .flex_col()
88 .w_full()
89 .child(
90 // Terminal Tabs.
91 div()
92 .w_full()
93 .flex()
94 .bg(cx.theme().colors().surface_background)
95 .child(
96 div().px_1().flex().flex_none().gap_2().child(
97 div()
98 .flex()
99 .items_center()
100 .gap_px()
101 .child(
102 IconButton::new("arrow_left", Icon::ArrowLeft).state(
103 InteractionState::Enabled.if_enabled(can_navigate_back),
104 ),
105 )
106 .child(IconButton::new("arrow_right", Icon::ArrowRight).state(
107 InteractionState::Enabled.if_enabled(can_navigate_forward),
108 )),
109 ),
110 )
111 .child(
112 div().w_0().flex_1().h_full().child(
113 div()
114 .flex()
115 .child(
116 Tab::new(1)
117 .title("zed — fish".to_string())
118 .icon(Icon::Terminal)
119 .close_side(IconSide::Right)
120 .current(true),
121 )
122 .child(
123 Tab::new(2)
124 .title("zed — fish".to_string())
125 .icon(Icon::Terminal)
126 .close_side(IconSide::Right)
127 .current(false),
128 ),
129 ),
130 ),
131 )
132 // Terminal Pane.
133 .child(
134 Pane::new(
135 "terminal",
136 Size {
137 width: relative(1.).into(),
138 height: rems(36.).into(),
139 },
140 )
141 .child(crate::static_data::terminal_buffer(cx)),
142 )
143 }
144}
145
146#[cfg(feature = "stories")]
147pub use stories::*;
148
149#[cfg(feature = "stories")]
150mod stories {
151 use super::*;
152 use crate::Story;
153 use gpui::{Div, Render};
154 pub struct TerminalStory;
155
156 impl Render<Self> for TerminalStory {
157 type Element = Div<Self>;
158
159 fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
160 Story::container(cx)
161 .child(Story::title_for::<_, Terminal>(cx))
162 .child(Story::label(cx, "Default"))
163 .child(Terminal::new())
164 }
165 }
166}