diff --git a/crates/storybook2/src/stories/components.rs b/crates/storybook2/src/stories/components.rs index 0097c67e0e..d1b30fbbf0 100644 --- a/crates/storybook2/src/stories/components.rs +++ b/crates/storybook2/src/stories/components.rs @@ -2,3 +2,4 @@ pub mod assistant_panel; pub mod buffer; pub mod panel; pub mod project_panel; +pub mod workspace; diff --git a/crates/storybook2/src/stories/components/workspace.rs b/crates/storybook2/src/stories/components/workspace.rs new file mode 100644 index 0000000000..e9d8b4ace2 --- /dev/null +++ b/crates/storybook2/src/stories/components/workspace.rs @@ -0,0 +1,22 @@ +use std::marker::PhantomData; + +use ui::prelude::*; +use ui::WorkspaceElement; + +#[derive(Element)] +pub struct WorkspaceStory { + state_type: PhantomData, +} + +impl WorkspaceStory { + pub fn new() -> Self { + Self { + state_type: PhantomData, + } + } + + fn render(&mut self, cx: &mut ViewContext) -> impl Element { + // Just render the workspace without any story boilerplate. + WorkspaceElement::new() + } +} diff --git a/crates/storybook2/src/story_selector.rs b/crates/storybook2/src/story_selector.rs index 519befa7cd..4823b0b9bf 100644 --- a/crates/storybook2/src/story_selector.rs +++ b/crates/storybook2/src/story_selector.rs @@ -38,6 +38,7 @@ pub enum ComponentStory { Buffer, Panel, ProjectPanel, + Workspace, } impl ComponentStory { @@ -51,6 +52,7 @@ impl ComponentStory { Self::Buffer => components::buffer::BufferStory::new().into_any(), Self::Panel => components::panel::PanelStory::new().into_any(), Self::ProjectPanel => components::project_panel::ProjectPanelStory::new().into_any(), + Self::Workspace => components::workspace::WorkspaceStory::new().into_any(), } } } diff --git a/crates/storybook2/src/workspace.rs b/crates/storybook2/src/workspace.rs index 377dbfe81b..4875c61a57 100644 --- a/crates/storybook2/src/workspace.rs +++ b/crates/storybook2/src/workspace.rs @@ -2,7 +2,7 @@ use gpui3::{ div, img, svg, view, Context, Element, ParentElement, RootView, StyleHelpers, View, ViewContext, WindowContext, }; -use ui::prelude::*; +use ui::{prelude::*}; use ui::{themed, Panel, Stack}; use crate::{ @@ -30,6 +30,7 @@ impl Workspace { fn render(&mut self, cx: &mut ViewContext) -> impl Element { themed(rose_pine_dawn(), cx, |cx| { let theme = theme(cx); + div() .size_full() .v_stack() diff --git a/crates/ui2/src/components.rs b/crates/ui2/src/components.rs index 993f0799fb..438db9b93a 100644 --- a/crates/ui2/src/components.rs +++ b/crates/ui2/src/components.rs @@ -4,6 +4,7 @@ mod icon_button; mod list; mod panel; mod project_panel; +mod workspace; pub use assistant_panel::*; pub use buffer::*; @@ -11,3 +12,4 @@ pub use icon_button::*; pub use list::*; pub use panel::*; pub use project_panel::*; +pub use workspace::*; diff --git a/crates/ui2/src/components/workspace.rs b/crates/ui2/src/components/workspace.rs new file mode 100644 index 0000000000..c384e02678 --- /dev/null +++ b/crates/ui2/src/components/workspace.rs @@ -0,0 +1,202 @@ +use std::marker::PhantomData; +use std::sync::Arc; + +use chrono::DateTime; +use gpui3::{relative, rems, Size}; + +use crate::prelude::*; +use crate::{theme, v_stack, Panel, PanelAllowedSides, PanelSide, ProjectPanel}; + +#[derive(Element)] +pub struct WorkspaceElement { + state_type: PhantomData, + left_panel_scroll_state: ScrollState, + right_panel_scroll_state: ScrollState, + tab_bar_scroll_state: ScrollState, + bottom_panel_scroll_state: ScrollState, +} + +impl WorkspaceElement { + pub fn new() -> Self { + Self { + state_type: PhantomData, + left_panel_scroll_state: ScrollState::default(), + right_panel_scroll_state: ScrollState::default(), + tab_bar_scroll_state: ScrollState::default(), + bottom_panel_scroll_state: ScrollState::default(), + } + } + + pub fn render(&mut self, cx: &mut ViewContext) -> impl Element { + let theme = theme(cx).clone(); + + // let temp_size = rems(36.).into(); + + // let root_group = PaneGroup::new_groups( + // vec![ + // PaneGroup::new_panes( + // vec![ + // Pane::new( + // ScrollState::default(), + // Size { + // width: relative(1.).into(), + // height: temp_size, + // }, + // |_, payload| { + // let theme = payload.downcast_ref::>().unwrap(); + + // vec![EditorPane::new(hello_world_rust_editor_with_status_example( + // &theme, + // )) + // .into_any()] + // }, + // Box::new(theme.clone()), + // ), + // Pane::new( + // ScrollState::default(), + // Size { + // width: relative(1.).into(), + // height: temp_size, + // }, + // |_, _| vec![Terminal::new().into_any()], + // Box::new(()), + // ), + // ], + // SplitDirection::Vertical, + // ), + // PaneGroup::new_panes( + // vec![Pane::new( + // ScrollState::default(), + // Size { + // width: relative(1.).into(), + // height: relative(1.).into(), + // }, + // |_, payload| { + // let theme = payload.downcast_ref::>().unwrap(); + + // vec![EditorPane::new(hello_world_rust_editor_with_status_example( + // &theme, + // )) + // .into_any()] + // }, + // Box::new(theme.clone()), + // )], + // SplitDirection::Vertical, + // ), + // ], + // SplitDirection::Horizontal, + // ); + + div() + .relative() + .size_full() + .flex() + .flex_col() + .font("Zed Sans Extended") + .gap_0() + .justify_start() + .items_start() + .text_color(theme.lowest.base.default.foreground) + .fill(theme.lowest.base.default.background) + // .child(TitleBar::new(cx).set_livestream(Some(Livestream { + // players: random_players_with_call_status(7), + // channel: Some("gpui2-ui".to_string()), + // }))) + .child( + div() + .flex_1() + .w_full() + .flex() + .flex_row() + .overflow_hidden() + .border_t() + .border_b() + .border_color(theme.lowest.base.default.border) + .child( + Panel::new( + self.left_panel_scroll_state.clone(), + |_, payload| vec![ProjectPanel::new(ScrollState::default()).into_any()], + Box::new(()), + ) + .side(PanelSide::Left), + ) + .child( + v_stack() + .flex_1() + .h_full() + .child( + div() + .flex() + .flex_1() + // CSS Hack: Flex 1 has to have a set height to properly fill the space + // Or it will give you a height of 0 + .h_px(), // .child(root_group), + ) + .child( + Panel::new( + self.bottom_panel_scroll_state.clone(), + |_, _| { + vec![ + // Terminal::new().into_any() + ] + }, + Box::new(()), + ) + .allowed_sides(PanelAllowedSides::BottomOnly) + .side(PanelSide::Bottom), + ), + ) + .child( + Panel::new( + self.right_panel_scroll_state.clone(), + |_, payload| vec![ProjectPanel::new(ScrollState::default()).into_any()], + Box::new(()), + ) + .side(PanelSide::Right), + ), // .child( + // Panel::new( + // self.right_panel_scroll_state.clone(), + // |_, payload| { + // vec![ChatPanel::new(ScrollState::default()) + // .with_messages(vec![ + // ChatMessage::new( + // "osiewicz".to_string(), + // "is this thing on?".to_string(), + // DateTime::parse_from_rfc3339( + // "2023-09-27T15:40:52.707Z", + // ) + // .unwrap() + // .naive_local(), + // ), + // ChatMessage::new( + // "maxdeviant".to_string(), + // "Reading you loud and clear!".to_string(), + // DateTime::parse_from_rfc3339( + // "2023-09-28T15:40:52.707Z", + // ) + // .unwrap() + // .naive_local(), + // ), + // ]) + // .into_any()] + // }, + // Box::new(()), + // ) + // .side(PanelSide::Right), + // ), + ) + // .child(StatusBar::new()) + // An example of a toast is below + // Currently because of stacking order this gets obscured by other elements + + // .child(Toast::new( + // ToastOrigin::Bottom, + // |_, payload| { + // let theme = payload.downcast_ref::>().unwrap(); + + // vec![Label::new("label").into_any()] + // }, + // Box::new(theme.clone()), + // )) + } +}