Add Terminal component

This commit is contained in:
Marshall Bowers 2023-10-06 18:50:49 -04:00
parent 8db7f7ed37
commit 82577b4acc
6 changed files with 161 additions and 52 deletions

View file

@ -3,4 +3,5 @@ pub mod buffer;
pub mod panel; pub mod panel;
pub mod project_panel; pub mod project_panel;
pub mod tab; pub mod tab;
pub mod terminal;
pub mod workspace; pub mod workspace;

View file

@ -0,0 +1,26 @@
use std::marker::PhantomData;
use ui::prelude::*;
use ui::Terminal;
use crate::story::Story;
#[derive(Element)]
pub struct TerminalStory<S: 'static + Send + Sync + Clone> {
state_type: PhantomData<S>,
}
impl<S: 'static + Send + Sync + Clone> TerminalStory<S> {
pub fn new() -> Self {
Self {
state_type: PhantomData,
}
}
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
Story::container(cx)
.child(Story::title_for::<_, Terminal<S>>(cx))
.child(Story::label(cx, "Default"))
.child(Terminal::new())
}
}

View file

@ -39,6 +39,7 @@ pub enum ComponentStory {
Panel, Panel,
ProjectPanel, ProjectPanel,
Tab, Tab,
Terminal,
Workspace, Workspace,
} }
@ -54,6 +55,7 @@ impl ComponentStory {
Self::Panel => components::panel::PanelStory::new().into_any(), Self::Panel => components::panel::PanelStory::new().into_any(),
Self::ProjectPanel => components::project_panel::ProjectPanelStory::new().into_any(), Self::ProjectPanel => components::project_panel::ProjectPanelStory::new().into_any(),
Self::Tab => components::tab::TabStory::new().into_any(), Self::Tab => components::tab::TabStory::new().into_any(),
Self::Terminal => components::terminal::TerminalStory::new().into_any(),
Self::Workspace => components::workspace::WorkspaceStory::new().into_any(), Self::Workspace => components::workspace::WorkspaceStory::new().into_any(),
} }
} }

View file

@ -7,6 +7,7 @@ mod panes;
mod project_panel; mod project_panel;
mod status_bar; mod status_bar;
mod tab; mod tab;
mod terminal;
mod workspace; mod workspace;
pub use assistant_panel::*; pub use assistant_panel::*;
@ -18,4 +19,5 @@ pub use panes::*;
pub use project_panel::*; pub use project_panel::*;
pub use status_bar::*; pub use status_bar::*;
pub use tab::*; pub use tab::*;
pub use terminal::*;
pub use workspace::*; pub use workspace::*;

View file

@ -0,0 +1,89 @@
use std::marker::PhantomData;
use std::sync::Arc;
use gpui3::{relative, rems, Size};
use crate::prelude::*;
use crate::{theme, Icon, IconButton, Pane, Tab};
#[derive(Element)]
pub struct Terminal<S: 'static + Send + Sync + Clone> {
state_type: PhantomData<S>,
}
impl<S: 'static + Send + Sync + Clone> Terminal<S> {
pub fn new() -> Self {
Self {
state_type: PhantomData,
}
}
fn render(&mut self, cx: &mut ViewContext<S>) -> impl Element<State = S> {
let theme = theme(cx);
let can_navigate_back = true;
let can_navigate_forward = false;
div()
.flex()
.flex_col()
.w_full()
.child(
// Terminal Tabs.
div()
.w_full()
.flex()
.fill(theme.middle.base.default.background)
.child(
div().px_1().flex().flex_none().gap_2().child(
div()
.flex()
.items_center()
.gap_px()
.child(
IconButton::new(Icon::ArrowLeft).state(
InteractionState::Enabled.if_enabled(can_navigate_back),
),
)
.child(IconButton::new(Icon::ArrowRight).state(
InteractionState::Enabled.if_enabled(can_navigate_forward),
)),
),
)
.child(
div().w_0().flex_1().h_full().child(
div()
.flex()
.child(
Tab::new()
.title("zed — fish".to_string())
.icon(Icon::Terminal)
.close_side(IconSide::Right)
.current(true),
)
.child(
Tab::new()
.title("zed — fish".to_string())
.icon(Icon::Terminal)
.close_side(IconSide::Right)
.current(false),
),
),
),
)
// Terminal Pane.
.child(Pane::new(
ScrollState::default(),
Size {
width: relative(1.).into(),
height: rems(36.).into(),
},
|_, payload| {
let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
vec![crate::static_data::terminal_buffer(&theme).into_any()]
},
Box::new(theme),
))
}
}

View file

@ -4,8 +4,11 @@ use std::sync::Arc;
use chrono::DateTime; use chrono::DateTime;
use gpui3::{relative, rems, Size}; use gpui3::{relative, rems, Size};
use crate::{prelude::*, Pane, PaneGroup, SplitDirection}; use crate::prelude::*;
use crate::{theme, v_stack, Panel, PanelAllowedSides, PanelSide, ProjectPanel, StatusBar}; use crate::{
theme, v_stack, Pane, PaneGroup, Panel, PanelAllowedSides, PanelSide, ProjectPanel,
SplitDirection, StatusBar, Terminal,
};
#[derive(Element)] #[derive(Element)]
pub struct WorkspaceElement<S: 'static + Send + Sync + Clone> { pub struct WorkspaceElement<S: 'static + Send + Sync + Clone> {
@ -46,13 +49,10 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
let theme = payload.downcast_ref::<Arc<Theme>>().unwrap(); let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
vec![ vec![
div() Terminal::new().into_any(), // EditorPane::new(hello_world_rust_editor_with_status_example(
.w_full() // &theme,
.fill(gpui3::rgb::<gpui3::Hsla>(0xff0000)) // ))
.into_any(), // EditorPane::new(hello_world_rust_editor_with_status_example( // .into_any()
// &theme,
// ))
// .into_any()
] ]
}, },
Box::new(theme.clone()), Box::new(theme.clone()),
@ -63,15 +63,7 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
width: relative(1.).into(), width: relative(1.).into(),
height: temp_size, height: temp_size,
}, },
|_, _| { |_, _| vec![Terminal::new().into_any()],
vec![
div()
.w_full()
.fill(gpui3::rgb::<gpui3::Hsla>(0x00ff00))
.into_any(),
// Terminal::new().into_any()
]
},
Box::new(()), Box::new(()),
), ),
], ],
@ -88,10 +80,7 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
let theme = payload.downcast_ref::<Arc<Theme>>().unwrap(); let theme = payload.downcast_ref::<Arc<Theme>>().unwrap();
vec![ vec![
div() Terminal::new().into_any(),
.w_full()
.fill(gpui3::rgb::<gpui3::Hsla>(0x0000ff))
.into_any(),
// EditorPane::new(hello_world_rust_editor_with_status_example( // EditorPane::new(hello_world_rust_editor_with_status_example(
// &theme, // &theme,
// )) // ))
@ -175,36 +164,36 @@ impl<S: 'static + Send + Sync + Clone> WorkspaceElement<S> {
.side(PanelSide::Right), .side(PanelSide::Right),
), ),
// .child( // .child(
// Panel::new( // Panel::new(
// self.right_panel_scroll_state.clone(), // self.right_panel_scroll_state.clone(),
// |_, payload| { // |_, payload| {
// vec![ChatPanel::new(ScrollState::default()) // vec![ChatPanel::new(ScrollState::default())
// .with_messages(vec![ // .with_messages(vec![
// ChatMessage::new( // ChatMessage::new(
// "osiewicz".to_string(), // "osiewicz".to_string(),
// "is this thing on?".to_string(), // "is this thing on?".to_string(),
// DateTime::parse_from_rfc3339( // DateTime::parse_from_rfc3339(
// "2023-09-27T15:40:52.707Z", // "2023-09-27T15:40:52.707Z",
// ) // )
// .unwrap() // .unwrap()
// .naive_local(), // .naive_local(),
// ), // ),
// ChatMessage::new( // ChatMessage::new(
// "maxdeviant".to_string(), // "maxdeviant".to_string(),
// "Reading you loud and clear!".to_string(), // "Reading you loud and clear!".to_string(),
// DateTime::parse_from_rfc3339( // DateTime::parse_from_rfc3339(
// "2023-09-28T15:40:52.707Z", // "2023-09-28T15:40:52.707Z",
// ) // )
// .unwrap() // .unwrap()
// .naive_local(), // .naive_local(),
// ), // ),
// ]) // ])
// .into_any()] // .into_any()]
// }, // },
// Box::new(()), // Box::new(()),
// ) // )
// .side(PanelSide::Right), // .side(PanelSide::Right),
// ), // ),
) )
.child(StatusBar::new()) .child(StatusBar::new())
// An example of a toast is below // An example of a toast is below