diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 6913e1c0b6..c13e5e0bc3 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -2,7 +2,6 @@ use crate::theme::Theme; use ::theme as legacy_theme; -use collab_panel::collab_panel; use element_ext::ElementExt; use gpui2::{serde_json, vec2f, view, Element, RectF, ViewContext, WindowBounds}; use legacy_theme::ThemeSettings; @@ -30,7 +29,7 @@ fn main() { cx.add_window( gpui2::WindowOptions { - bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(260., 800.))), + bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(1400., 900.))), center: true, ..Default::default() }, @@ -41,7 +40,7 @@ fn main() { } fn storybook(cx: &mut ViewContext) -> impl Element { - collab_panel().themed(current_theme(cx)) + workspace().themed(current_theme(cx)) } // Nathan: During the transition to gpui2, we will include the base theme on the legacy Theme struct. @@ -64,6 +63,7 @@ fn current_theme(cx: &mut ViewContext) -> Theme { use anyhow::{anyhow, Result}; use gpui2::AssetSource; use rust_embed::RustEmbed; +use workspace::workspace; #[derive(RustEmbed)] #[folder = "../../assets"] diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index a7a3f379dd..c241697610 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -1,9 +1,330 @@ use crate::theme::theme; use gpui2::{ - elements::div, geometry::pixels, style::StyleHelpers, Element, IntoElement, ParentElement, - ViewContext, + elements::{div, svg}, + geometry::pixels, + style::{StyleHelpers, Styleable}, + Element, IntoElement, ParentElement, ViewContext, }; +#[derive(Element)] +struct TitleBar; + +pub fn titlebar() -> impl Element { + TitleBar +} + +impl TitleBar { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + div() + .flex() + .items_center() + .justify_between() + .w_full() + .h_8() + .fill(theme.lowest.base.default.background) + .child(self.left_group(cx)) + .child(self.right_group(cx)) + } + + fn left_group(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + div() + .flex() + .items_center() + .h_full() + .gap_4() + .px_2() + // === Traffic Lights === // + .child( + div() + .flex() + .items_center() + .gap_2() + .child( + div() + .w_3() + .h_3() + // .rounded_full() + .fill(theme.lowest.positive.default.foreground), + ) + .child( + div() + .w_3() + .h_3() + // .rounded_full() + .fill(theme.lowest.warning.default.foreground), + ) + .child( + div() + .w_3() + .h_3() + // .rounded_full() + .fill(theme.lowest.negative.default.foreground), + ), + ) + // === Project Info === // + .child( + div() + .flex() + .items_center() + .gap_1() + .child( + div() + .h_full() + .flex() + .items_center() + .justify_center() + .px_1() + .hover() + .fill(theme.lowest.base.hovered.background) + .active() + .fill(theme.lowest.base.pressed.background) + .child(div().text_sm().child("project")), + ) + .child( + div() + .h_full() + .flex() + .items_center() + .justify_center() + .px_1() + .text_color(theme.lowest.variant.default.foreground) + .hover() + .fill(theme.lowest.base.hovered.background) + .active() + .fill(theme.lowest.base.pressed.background) + .child(div().text_sm().child("branch")), + ), + ) + } + + fn right_group(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + div() + .flex() + .items_center() + .h_full() + .gap_4() + .px_2() + // === Comms === // + .child( + div() + .flex() + .items_center() + .gap_1() + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/microphone.svg") + .w_4() + .h_4() + .fill(theme.lowest.base.default.foreground), + ), + ) + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/screen.svg") + .w_4() + .h_4() + .fill(theme.lowest.base.default.foreground), + ), + ) + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/exit.svg") + .w_4() + .h_4() + .fill(theme.lowest.base.default.foreground), + ), + ), + ) + } +} + +// ================================================================================ // + +#[derive(Element)] +struct StatusBar; + +pub fn statusbar() -> impl Element { + StatusBar +} + +impl StatusBar { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + div() + .flex() + .items_center() + .justify_between() + .w_full() + .h_8() + .fill(theme.lowest.base.default.background) + .child(self.left_group(cx)) + .child(self.right_group(cx)) + } + + fn left_group(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + div() + .flex() + .items_center() + .h_full() + .gap_4() + .px_2() + // === Tools === // + .child( + div() + .flex() + .items_center() + .gap_1() + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/project.svg") + .w_4() + .h_4() + .fill(theme.lowest.base.default.foreground), + ), + ) + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/conversations.svg") + .w_4() + .h_4() + .fill(theme.lowest.base.default.foreground), + ), + ) + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/file_icons/notebook.svg") + .w_4() + .h_4() + .fill(theme.lowest.accent.default.foreground), + ), + ), + ) + // === Diagnostics === // + .child( + div().flex().items_center().gap_2() + .child( + div() + .h_full() + .flex() + .items_center() + .justify_center() + .gap_0p5() + .px_1() + .text_color(theme.lowest.variant.default.foreground) + .hover() + .fill(theme.lowest.base.hovered.background) + .active() + .fill(theme.lowest.base.pressed.background) + .child( + svg() + .path("icons/error.svg") + .w_4() + .h_4() + .fill(theme.lowest.negative.default.foreground), + ) + .child(div().text_sm().child("2")), + ) + .child(div().text_sm().text_color(theme.lowest.variant.default.foreground).child("Something is wrong")), + + ) + } + + fn right_group(&mut self, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + div() + .flex() + .items_center() + .h_full() + .gap_4() + .px_2() + // === Tools === // + .child( + div() + .flex() + .items_center() + .gap_1() + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/check_circle.svg") + .w_4() + .h_4() + .fill(theme.lowest.base.default.foreground), + ), + ) + .child( + div() + .w_6() + .h_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("icons/copilot.svg") + .w_4() + .h_4() + .fill(theme.lowest.accent.default.foreground), + ), + ), + ) + } +} + +// ================================================================================ // + #[derive(Element)] struct WorkspaceElement; @@ -15,27 +336,15 @@ impl WorkspaceElement { fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { let theme = theme(cx); div() - .full() + .h_full() + .w_full() .flex() .flex_col() + .font("Zed Sans Extended") + .text_color(theme.lowest.base.default.foreground) .fill(theme.middle.base.default.background) - .child(self.title_bar(cx)) - .child(self.stage(cx)) - .child(self.status_bar(cx)) - } - - fn title_bar(&mut self, cx: &mut ViewContext) -> impl IntoElement { - let theme = theme(cx); - div() - .h(pixels(cx.titlebar_height())) - .fill(theme.lowest.base.default.background) - } - - fn status_bar(&mut self, cx: &mut ViewContext) -> impl IntoElement { - div().h(pixels(cx.titlebar_height())) //.fill(colors.base(0.)) - } - - fn stage(&mut self, cx: &mut ViewContext) -> impl IntoElement { - div().flex_grow() + .child(titlebar()) + .child(div().child("panes")) + .child(statusbar()) } }