diff --git a/crates/gpui/src/elements/flex.rs b/crates/gpui/src/elements/flex.rs index b142726994..5df283bfee 100644 --- a/crates/gpui/src/elements/flex.rs +++ b/crates/gpui/src/elements/flex.rs @@ -324,20 +324,24 @@ impl Element for Flex { // overall flex element and each child. We then align these points. So 0 would center // each child relative to the overall height/width of the flex. -1 puts children at // the start. 1 puts children at the end. - let cross_axis = self.axis.invert(); - let my_center = bounds.size().along(cross_axis) / 2.; - let my_target = my_center + my_center * self.child_alignment; + let aligned_child_origin = { + let cross_axis = self.axis.invert(); + let my_center = bounds.size().along(cross_axis) / 2.; + let my_target = my_center + my_center * self.child_alignment; - let child_center = child.size().along(cross_axis) / 2.; - let child_target = child_center + child_center * self.child_alignment; + let child_center = child.size().along(cross_axis) / 2.; + let child_target = child_center + child_center * self.child_alignment; - let mut aligned_child_origin = child_origin; - match self.axis { - Axis::Horizontal => aligned_child_origin - .set_y(aligned_child_origin.y() - (child_target - my_target)), - Axis::Vertical => aligned_child_origin - .set_x(aligned_child_origin.x() - (child_target - my_target)), - } + let mut aligned_child_origin = child_origin; + match self.axis { + Axis::Horizontal => aligned_child_origin + .set_y(aligned_child_origin.y() - (child_target - my_target)), + Axis::Vertical => aligned_child_origin + .set_x(aligned_child_origin.x() - (child_target - my_target)), + } + + aligned_child_origin + }; child.paint(aligned_child_origin, visible_bounds, cx); diff --git a/crates/welcome/src/welcome.rs b/crates/welcome/src/welcome.rs index f787a6cf24..f1d59ce7a1 100644 --- a/crates/welcome/src/welcome.rs +++ b/crates/welcome/src/welcome.rs @@ -1,14 +1,13 @@ use std::borrow::Cow; use gpui::{ - elements::{Canvas, Empty, Flex, Image, Label, MouseEventHandler, ParentElement, Stack, Svg}, - geometry::rect::RectF, - Action, Element, ElementBox, Entity, MouseButton, MouseRegion, MutableAppContext, - RenderContext, Subscription, View, ViewContext, + elements::{Empty, Flex, Image, Label, MouseEventHandler, ParentElement, Svg}, + Action, Element, ElementBox, Entity, MouseButton, MutableAppContext, RenderContext, + Subscription, View, ViewContext, }; use settings::{settings_file::SettingsFile, Settings, SettingsFileContent}; use theme::CheckboxStyle; -use workspace::{item::Item, Welcome, Workspace}; +use workspace::{item::Item, PaneBackdrop, Welcome, Workspace, WorkspaceId}; pub fn init(cx: &mut MutableAppContext) { cx.add_action(|workspace: &mut Workspace, _: &Welcome, cx| { @@ -43,89 +42,67 @@ impl View for WelcomePage { enum Metrics {} enum Diagnostics {} - let background = theme.editor.background; - - Stack::new() - .with_child( - // TODO: Can this be moved into the pane? - Canvas::new(move |bounds, visible_bounds, cx| { - let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - - cx.paint_layer(Some(visible_bounds), |cx| { - cx.scene.push_quad(gpui::Quad { - bounds: RectF::new(bounds.origin(), bounds.size()), - background: Some(background), - ..Default::default() - }) - }); - - cx.scene.push_mouse_region( - MouseRegion::new::(self_handle.id(), 0, visible_bounds) - .on_down(gpui::MouseButton::Left, |_, cx| cx.focus_parent_view()), - ); - }) - .boxed(), - ) - .with_child( - Flex::column() - .with_children([ - Flex::row() - .with_children([ - Image::new("images/zed-logo-90x90.png") - .constrained() - .with_width(90.) - .with_height(90.) - .aligned() - .contained() - .boxed(), - // Label::new("Zed", theme.editor.hover_popover.prose.clone()).boxed(), - ]) - .boxed(), - Label::new( - "Code at the speed of thought", - theme.editor.hover_popover.prose.clone(), - ) + PaneBackdrop::new( + self_handle.id(), + Flex::column() + .with_children([ + Flex::row() + .with_children([ + Image::new("images/zed-logo-90x90.png") + .constrained() + .with_width(90.) + .with_height(90.) + .aligned() + .contained() + .boxed(), + // Label::new("Zed", theme.editor.hover_popover.prose.clone()).boxed(), + ]) .boxed(), - self.render_cta_button(2, "Choose a theme", theme_selector::Toggle, cx), - self.render_cta_button(3, "Choose a keymap", theme_selector::Toggle, cx), - Flex::row() - .with_children([ - self.render_settings_checkbox::( - &theme.welcome.checkbox, - metrics, - cx, - |content, checked| { - content.telemetry.set_metrics(checked); - }, - ), - Label::new( - "Do you want to send telemetry?", - theme.editor.hover_popover.prose.clone(), - ) - .boxed(), - ]) - .align_children_center() - .boxed(), - Flex::row() - .with_children([ - self.render_settings_checkbox::( - &theme.welcome.checkbox, - diagnostics, - cx, - |content, checked| content.telemetry.set_diagnostics(checked), - ), - Label::new( - "Send crash reports", - theme.editor.hover_popover.prose.clone(), - ) - .boxed(), - ]) - .align_children_center() - .boxed(), - ]) + Label::new( + "Code at the speed of thought", + theme.editor.hover_popover.prose.clone(), + ) .boxed(), - ) - .boxed() + self.render_cta_button(2, "Choose a theme", theme_selector::Toggle, cx), + self.render_cta_button(3, "Choose a keymap", theme_selector::Toggle, cx), + Flex::row() + .with_children([ + self.render_settings_checkbox::( + &theme.welcome.checkbox, + metrics, + cx, + |content, checked| { + content.telemetry.set_metrics(checked); + }, + ), + Label::new( + "Do you want to send telemetry?", + theme.editor.hover_popover.prose.clone(), + ) + .boxed(), + ]) + .align_children_center() + .boxed(), + Flex::row() + .with_children([ + self.render_settings_checkbox::( + &theme.welcome.checkbox, + diagnostics, + cx, + |content, checked| content.telemetry.set_diagnostics(checked), + ), + Label::new( + "Send crash reports", + theme.editor.hover_popover.prose.clone(), + ) + .boxed(), + ]) + .align_children_center() + .boxed(), + ]) + .boxed(), + ) + .boxed() } } @@ -232,4 +209,11 @@ impl Item for WelcomePage { fn show_toolbar(&self) -> bool { false } + fn clone_on_split( + &self, + _workspace_id: WorkspaceId, + cx: &mut ViewContext, + ) -> Option { + Some(WelcomePage::new(cx)) + } } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 235df0202d..fe33996961 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -24,8 +24,8 @@ use gpui::{ keymap_matcher::KeymapContext, platform::{CursorStyle, NavigationDirection}, Action, AnyViewHandle, AnyWeakViewHandle, AppContext, AsyncAppContext, Entity, EventContext, - ModelHandle, MouseButton, MutableAppContext, PromptLevel, Quad, RenderContext, Task, View, - ViewContext, ViewHandle, WeakViewHandle, + ModelHandle, MouseButton, MouseRegion, MutableAppContext, PromptLevel, Quad, RenderContext, + Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath}; use serde::Deserialize; @@ -1706,6 +1706,93 @@ impl NavHistory { } } +pub struct PaneBackdrop { + child_view: usize, + child: ElementBox, +} +impl PaneBackdrop { + pub fn new(pane_item_view: usize, child: ElementBox) -> Self { + PaneBackdrop { + child, + child_view: pane_item_view, + } + } +} + +impl Element for PaneBackdrop { + type LayoutState = (); + + type PaintState = (); + + fn layout( + &mut self, + constraint: gpui::SizeConstraint, + cx: &mut gpui::LayoutContext, + ) -> (Vector2F, Self::LayoutState) { + let size = self.child.layout(constraint, cx); + (size, ()) + } + + fn paint( + &mut self, + bounds: RectF, + visible_bounds: RectF, + _: &mut Self::LayoutState, + cx: &mut gpui::PaintContext, + ) -> Self::PaintState { + let background = cx.global::().theme.editor.background; + + let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); + + cx.scene.push_quad(gpui::Quad { + bounds: RectF::new(bounds.origin(), bounds.size()), + background: Some(background), + ..Default::default() + }); + + let child_view_id = self.child_view; + cx.scene.push_mouse_region( + MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( + gpui::MouseButton::Left, + move |_, cx| { + let window_id = cx.window_id; + cx.focus(window_id, Some(child_view_id)) + }, + ), + ); + + cx.paint_layer(Some(bounds), |cx| { + self.child.paint(bounds.origin(), visible_bounds, cx) + }) + } + + fn rect_for_text_range( + &self, + range_utf16: std::ops::Range, + _bounds: RectF, + _visible_bounds: RectF, + _layout: &Self::LayoutState, + _paint: &Self::PaintState, + cx: &gpui::MeasurementContext, + ) -> Option { + self.child.rect_for_text_range(range_utf16, cx) + } + + fn debug( + &self, + _bounds: RectF, + _layout: &Self::LayoutState, + _paint: &Self::PaintState, + cx: &gpui::DebugContext, + ) -> serde_json::Value { + gpui::json::json!({ + "type": "Pane Back Drop", + "view": self.child_view, + "child": self.child.debug(cx), + }) + } +} + #[cfg(test)] mod tests { use std::sync::Arc;