From 33a808a49b61f2efe6e221b305b3f6028ab420c2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Nov 2023 20:41:09 +0100 Subject: [PATCH 1/3] WIP --- crates/gpui2/src/element.rs | 86 ++++----------------- crates/gpui2/src/elements/div.rs | 91 +++++++---------------- crates/gpui2/src/elements/img.rs | 13 +--- crates/gpui2/src/elements/svg.rs | 13 +--- crates/gpui2/src/elements/text.rs | 16 +--- crates/gpui2/src/elements/uniform_list.rs | 4 +- crates/gpui2/src/view.rs | 87 ++++++++-------------- crates/gpui2/src/window.rs | 16 +++- 8 files changed, 95 insertions(+), 231 deletions(-) diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 9db256a5722faef0bd3f47aa4ef569aa666a509f..3ee829df523aee8c84c78cd470d1e158fd3ee42a 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -10,21 +10,12 @@ pub trait Element { fn element_id(&self) -> Option; - /// Called to initialize this element for the current frame. If this - /// element had state in a previous frame, it will be passed in for the 3rd argument. - fn initialize( - &mut self, - view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState; - fn layout( &mut self, view_state: &mut V, - element_state: &mut Self::ElementState, + previous_element_state: Option, cx: &mut ViewContext, - ) -> LayoutId; + ) -> (LayoutId, Self::ElementState); fn paint( &mut self, @@ -96,7 +87,6 @@ pub trait ParentComponent { } trait ElementObject { - fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext); fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext) -> LayoutId; fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext); fn measure( @@ -123,9 +113,6 @@ struct RenderedElement> { enum ElementRenderPhase { #[default] Start, - Initialized { - frame_state: Option, - }, LayoutRequested { layout_id: LayoutId, frame_state: Option, @@ -157,42 +144,19 @@ where E: Element, E::ElementState: 'static, { - fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext) { - let frame_state = if let Some(id) = self.element.element_id() { - cx.with_element_state(id, |element_state, cx| { - let element_state = self.element.initialize(view_state, element_state, cx); - ((), element_state) - }); - None - } else { - let frame_state = self.element.initialize(view_state, None, cx); - Some(frame_state) - }; - - self.phase = ElementRenderPhase::Initialized { frame_state }; - } - fn layout(&mut self, state: &mut V, cx: &mut ViewContext) -> LayoutId { - let layout_id; - let mut frame_state; - match mem::take(&mut self.phase) { - ElementRenderPhase::Initialized { - frame_state: initial_frame_state, - } => { - frame_state = initial_frame_state; + let (layout_id, frame_state) = match mem::take(&mut self.phase) { + ElementRenderPhase::Start => { if let Some(id) = self.element.element_id() { - layout_id = cx.with_element_state(id, |element_state, cx| { - let mut element_state = element_state.unwrap(); - let layout_id = self.element.layout(state, &mut element_state, cx); - (layout_id, element_state) + let layout_id = cx.with_element_state(id, |element_state, cx| { + self.element.layout(state, element_state, cx) }); + (layout_id, None) } else { - layout_id = self - .element - .layout(state, frame_state.as_mut().unwrap(), cx); + let (layout_id, frame_state) = self.element.layout(state, None, cx); + (layout_id, Some(frame_state)) } } - ElementRenderPhase::Start => panic!("must call initialize before layout"), ElementRenderPhase::LayoutRequested { .. } | ElementRenderPhase::LayoutComputed { .. } | ElementRenderPhase::Painted { .. } => { @@ -244,10 +208,6 @@ where cx: &mut ViewContext, ) -> Size { if matches!(&self.phase, ElementRenderPhase::Start) { - self.initialize(view_state, cx); - } - - if matches!(&self.phase, ElementRenderPhase::Initialized { .. }) { self.layout(view_state, cx); } @@ -290,10 +250,7 @@ where cx: &mut ViewContext, ) { self.measure(available_space, view_state, cx); - // Ignore the element offset when drawing this element, as the origin is already specified - // in absolute terms. - origin -= cx.element_offset(); - cx.with_element_offset(origin, |cx| self.paint(view_state, cx)) + cx.with_absolute_element_offset(origin, |cx| self.paint(view_state, cx)) } } @@ -309,10 +266,6 @@ impl AnyElement { AnyElement(Box::new(RenderedElement::new(element))) } - pub fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext) { - self.0.initialize(view_state, cx); - } - pub fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext) -> LayoutId { self.0.layout(view_state, cx) } @@ -393,25 +346,16 @@ where None } - fn initialize( + fn layout( &mut self, view_state: &mut V, - _rendered_element: Option, + _: Option, cx: &mut ViewContext, - ) -> Self::ElementState { + ) -> (LayoutId, Self::ElementState) { let render = self.take().unwrap(); let mut rendered_element = (render)(view_state, cx).render(); - rendered_element.initialize(view_state, cx); - rendered_element - } - - fn layout( - &mut self, - view_state: &mut V, - rendered_element: &mut Self::ElementState, - cx: &mut ViewContext, - ) -> LayoutId { - rendered_element.layout(view_state, cx) + let layout_id = rendered_element.layout(view_state, cx); + (layout_id, rendered_element) } fn paint( diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 1f9b2b020abafd626b45453190dedbab7c406874..3a3ad5936ebba2ca0567f0e1eb926a708617717a 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -617,46 +617,36 @@ impl Element for Div { self.interactivity.element_id.clone() } - fn initialize( - &mut self, - view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - let interactive_state = self - .interactivity - .initialize(element_state.map(|s| s.interactive_state), cx); - - for child in &mut self.children { - child.initialize(view_state, cx); - } - - DivState { - interactive_state, - child_layout_ids: SmallVec::new(), - } - } - fn layout( &mut self, view_state: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> crate::LayoutId { + ) -> (LayoutId, Self::ElementState) { + let mut child_layout_ids = SmallVec::new(); let mut interactivity = mem::take(&mut self.interactivity); - let layout_id = - interactivity.layout(&mut element_state.interactive_state, cx, |style, cx| { + let (layout_id, interactive_state) = interactivity.layout( + element_state.map(|s| s.interactive_state), + cx, + |style, cx| { cx.with_text_style(style.text_style().cloned(), |cx| { - element_state.child_layout_ids = self + child_layout_ids = self .children .iter_mut() .map(|child| child.layout(view_state, cx)) .collect::>(); - cx.request_layout(&style, element_state.child_layout_ids.iter().copied()) + cx.request_layout(&style, child_layout_ids.iter().copied()) }) - }); + }, + ); self.interactivity = interactivity; - layout_id + ( + layout_id, + DivState { + interactive_state, + child_layout_ids, + }, + ) } fn paint( @@ -766,11 +756,12 @@ impl Interactivity where V: 'static, { - pub fn initialize( + pub fn layout( &mut self, element_state: Option, cx: &mut ViewContext, - ) -> InteractiveElementState { + f: impl FnOnce(Style, &mut ViewContext) -> LayoutId, + ) -> (LayoutId, InteractiveElementState) { let mut element_state = element_state.unwrap_or_default(); // Ensure we store a focus handle in our element state if we're focusable. @@ -785,17 +776,9 @@ where }); } - element_state - } - - pub fn layout( - &mut self, - element_state: &mut InteractiveElementState, - cx: &mut ViewContext, - f: impl FnOnce(Style, &mut ViewContext) -> LayoutId, - ) -> LayoutId { - let style = self.compute_style(None, element_state, cx); - f(style, cx) + let style = self.compute_style(None, &mut element_state, cx); + let layout_id = f(style, cx); + (layout_id, element_state) } pub fn paint( @@ -1327,21 +1310,12 @@ where self.element.element_id() } - fn initialize( - &mut self, - view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - self.element.initialize(view_state, element_state, cx) - } - fn layout( &mut self, view_state: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { self.element.layout(view_state, element_state, cx) } @@ -1422,21 +1396,12 @@ where self.element.element_id() } - fn initialize( - &mut self, - view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - self.element.initialize(view_state, element_state, cx) - } - fn layout( &mut self, view_state: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { self.element.layout(view_state, element_state, cx) } diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index c5c5fb628e31989f6a575a9b26f11f4336d7857d..1080135fe16edcabdf6c2176e264bd551be5011d 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -48,21 +48,12 @@ impl Element for Img { self.interactivity.element_id.clone() } - fn initialize( - &mut self, - _view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - self.interactivity.initialize(element_state, cx) - } - fn layout( &mut self, _view_state: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { self.interactivity.layout(element_state, cx, |style, cx| { cx.request_layout(&style, None) }) diff --git a/crates/gpui2/src/elements/svg.rs b/crates/gpui2/src/elements/svg.rs index 4b441ad425ee1bc4fe9b860635d8214ace1c21c3..c1c7691fbf41371cca9cba173485523df2dd7fb3 100644 --- a/crates/gpui2/src/elements/svg.rs +++ b/crates/gpui2/src/elements/svg.rs @@ -37,21 +37,12 @@ impl Element for Svg { self.interactivity.element_id.clone() } - fn initialize( - &mut self, - _view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - self.interactivity.initialize(element_state, cx) - } - fn layout( &mut self, _view_state: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { self.interactivity.layout(element_state, cx, |style, cx| { cx.request_layout(&style, None) }) diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index 93d087833a563b37b557fc1c09c65ce67136e8ad..1081154e7dfd90a08955ad63487b6e045791b57f 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -76,21 +76,13 @@ impl Element for Text { None } - fn initialize( - &mut self, - _view_state: &mut V, - element_state: Option, - _cx: &mut ViewContext, - ) -> Self::ElementState { - element_state.unwrap_or_default() - } - fn layout( &mut self, _view: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { + let element_state = element_state.unwrap_or_default(); let text_system = cx.text_system().clone(); let text_style = cx.text_style(); let font_size = text_style.font_size.to_pixels(cx.rem_size()); @@ -148,7 +140,7 @@ impl Element for Text { } }); - layout_id + (layout_id, element_state) } fn paint( diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 340a2cbf87c79c93f54b8610cd44b26da9e41e4d..97361396199f69c1875800e4bb2f6a201b502ee4 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -131,9 +131,9 @@ impl Element for UniformList { fn layout( &mut self, _view_state: &mut V, - element_state: &mut Self::ElementState, + element_state: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { let max_items = self.item_count; let item_size = element_state.item_size; let rem_size = cx.rem_size(); diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 3edaa900b0435233f669ff553e01c1cdb9cb1adc..1ce1c4d34916b41202e8ff407c3f6993b25b67c7 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -1,7 +1,7 @@ use crate::{ private::Sealed, AnyBox, AnyElement, AnyModel, AnyWeakModel, AppContext, AvailableSpace, - Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId, Model, Pixels, - Size, ViewContext, VisualContext, WeakModel, WindowContext, + BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId, + Model, Pixels, Point, Size, ViewContext, VisualContext, WeakModel, WindowContext, }; use anyhow::{Context, Result}; use std::{ @@ -155,8 +155,7 @@ impl Eq for WeakView {} #[derive(Clone, Debug)] pub struct AnyView { model: AnyModel, - initialize: fn(&AnyView, &mut WindowContext) -> AnyBox, - layout: fn(&AnyView, &mut AnyBox, &mut WindowContext) -> LayoutId, + layout: fn(&AnyView, &mut WindowContext) -> (LayoutId, Box), paint: fn(&AnyView, &mut AnyBox, &mut WindowContext), } @@ -164,7 +163,6 @@ impl AnyView { pub fn downgrade(&self) -> AnyWeakView { AnyWeakView { model: self.model.downgrade(), - initialize: self.initialize, layout: self.layout, paint: self.paint, } @@ -175,7 +173,6 @@ impl AnyView { Ok(model) => Ok(View { model }), Err(model) => Err(Self { model, - initialize: self.initialize, layout: self.layout, paint: self.paint, }), @@ -186,13 +183,19 @@ impl AnyView { self.model.entity_type } - pub(crate) fn draw(&self, available_space: Size, cx: &mut WindowContext) { - let mut rendered_element = (self.initialize)(self, cx); - let layout_id = (self.layout)(self, &mut rendered_element, cx); - cx.window - .layout_engine - .compute_layout(layout_id, available_space); - (self.paint)(self, &mut rendered_element, cx); + pub(crate) fn draw( + &self, + origin: Point, + available_space: Size, + cx: &mut WindowContext, + ) { + cx.with_absolute_element_offset(origin, |cx| { + let (layout_id, mut rendered_element) = (self.layout)(self, cx); + cx.window + .layout_engine + .compute_layout(layout_id, available_space); + (self.paint)(self, &mut rendered_element, cx); + }) } } @@ -206,7 +209,6 @@ impl From> for AnyView { fn from(value: View) -> Self { AnyView { model: value.model.into_any(), - initialize: any_view::initialize::, layout: any_view::layout::, paint: any_view::paint::, } @@ -220,21 +222,12 @@ impl Element for AnyView { Some(self.model.entity_id.into()) } - fn initialize( - &mut self, - _view_state: &mut ParentViewState, - _element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - (self.initialize)(self, cx) - } - fn layout( &mut self, _view_state: &mut ParentViewState, - rendered_element: &mut Self::ElementState, + rendered_element: Option, cx: &mut ViewContext, - ) -> LayoutId { + ) -> (LayoutId, Self::ElementState) { (self.layout)(self, rendered_element, cx) } @@ -251,8 +244,7 @@ impl Element for AnyView { pub struct AnyWeakView { model: AnyWeakModel, - initialize: fn(&AnyView, &mut WindowContext) -> AnyBox, - layout: fn(&AnyView, &mut AnyBox, &mut WindowContext) -> LayoutId, + layout: fn(&AnyView, &mut WindowContext) -> (LayoutId, Box), paint: fn(&AnyView, &mut AnyBox, &mut WindowContext), } @@ -261,7 +253,6 @@ impl AnyWeakView { let model = self.model.upgrade()?; Some(AnyView { model, - initialize: self.initialize, layout: self.layout, paint: self.paint, }) @@ -272,7 +263,6 @@ impl From> for AnyWeakView { fn from(view: WeakView) -> Self { Self { model: view.model.into(), - initialize: any_view::initialize::, layout: any_view::layout::, paint: any_view::paint::, } @@ -319,28 +309,19 @@ where Some(self.view.entity_id().into()) } - fn initialize( + fn layout( &mut self, _: &mut ParentViewState, _: Option, cx: &mut ViewContext, - ) -> Self::ElementState { + ) -> (LayoutId, Self::ElementState) { self.view.update(cx, |view, cx| { let mut element = self.component.take().unwrap().render(); - element.initialize(view, cx); - element + let layout_id = element.layout(view, cx); + (layout_id, element) }) } - fn layout( - &mut self, - _: &mut ParentViewState, - element: &mut Self::ElementState, - cx: &mut ViewContext, - ) -> LayoutId { - self.view.update(cx, |view, cx| element.layout(view, cx)) - } - fn paint( &mut self, _: Bounds, @@ -356,27 +337,17 @@ mod any_view { use crate::{AnyElement, AnyView, BorrowWindow, LayoutId, Render, WindowContext}; use std::any::Any; - pub(crate) fn initialize(view: &AnyView, cx: &mut WindowContext) -> Box { - cx.with_element_id(Some(view.model.entity_id), |cx| { - let view = view.clone().downcast::().unwrap(); - let element = view.update(cx, |view, cx| { - let mut element = AnyElement::new(view.render(cx)); - element.initialize(view, cx); - element - }); - Box::new(element) - }) - } - pub(crate) fn layout( view: &AnyView, - element: &mut Box, cx: &mut WindowContext, - ) -> LayoutId { + ) -> (LayoutId, Box) { cx.with_element_id(Some(view.model.entity_id), |cx| { let view = view.clone().downcast::().unwrap(); - let element = element.downcast_mut::>().unwrap(); - view.update(cx, |view, cx| element.layout(view, cx)) + view.update(cx, |view, cx| { + let mut element = AnyElement::new(view.render(cx)); + let layout_id = element.layout(view, cx); + (layout_id, Box::new(element) as Box) + }) }) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 0563c107c0b150fc8394acab0a4e3c2bbba4b2af..9c1951287124113c4b3934b314a5838dc2df2613 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1633,8 +1633,8 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { } } - /// Update the global element offset based on the given offset. This is used to implement - /// scrolling and position drag handles. + /// Update the global element offset relative to the current offset. This is used to implement + /// scrolling. fn with_element_offset( &mut self, offset: Point, @@ -1644,7 +1644,17 @@ pub trait BorrowWindow: BorrowMut + BorrowMut { return f(self); }; - let offset = self.element_offset() + offset; + let abs_offset = self.element_offset() + offset; + self.with_absolute_element_offset(abs_offset, f) + } + + /// Update the global element offset based on the given offset. This is used to implement + /// drag handles and other manual painting of elements. + fn with_absolute_element_offset( + &mut self, + offset: Point, + f: impl FnOnce(&mut Self) -> R, + ) -> R { self.window_mut() .current_frame .element_offset_stack From c6b374ebc9ba9efe852bd2111da2cb0aaca9bbaf Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 15 Nov 2023 14:11:19 -0700 Subject: [PATCH 2/3] Remove initialize method from Element trait --- crates/editor2/src/element.rs | 14 ++-- crates/gpui2/src/element.rs | 2 +- crates/gpui2/src/elements/uniform_list.rs | 84 ++++++++++------------- crates/gpui2/src/view.rs | 4 +- crates/gpui2/src/window.rs | 20 +++--- 5 files changed, 53 insertions(+), 71 deletions(-) diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 4d9a516f2b175f30ba0d968e82091aee7d76220a..de1b6f062244445960479710aeccddcfcd8e2bc6 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -2398,21 +2398,14 @@ impl Element for EditorElement { Some(self.editor_id.into()) } - fn initialize( + fn layout( &mut self, editor: &mut Editor, element_state: Option, cx: &mut gpui::ViewContext, - ) -> Self::ElementState { + ) -> (gpui::LayoutId, Self::ElementState) { editor.style = Some(self.style.clone()); // Long-term, we'd like to eliminate this. - } - fn layout( - &mut self, - editor: &mut Editor, - element_state: &mut Self::ElementState, - cx: &mut gpui::ViewContext, - ) -> gpui::LayoutId { let rem_size = cx.rem_size(); let mut style = Style::default(); style.size.width = relative(1.).into(); @@ -2421,7 +2414,8 @@ impl Element for EditorElement { EditorMode::AutoHeight { .. } => todo!(), EditorMode::Full => relative(1.).into(), }; - cx.request_layout(&style, None) + let layout_id = cx.request_layout(&style, None); + (layout_id, ()) } fn paint( diff --git a/crates/gpui2/src/element.rs b/crates/gpui2/src/element.rs index 3ee829df523aee8c84c78cd470d1e158fd3ee42a..221eb903fd4f7ef93df32558bbafef51d0518426 100644 --- a/crates/gpui2/src/element.rs +++ b/crates/gpui2/src/element.rs @@ -244,7 +244,7 @@ where fn draw( &mut self, - mut origin: Point, + origin: Point, available_space: Size, view_state: &mut V, cx: &mut ViewContext, diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index 97361396199f69c1875800e4bb2f6a201b502ee4..773f9ec8aacfb2ce0ac77cc96b4c30311a406ba5 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -108,62 +108,54 @@ impl Element for UniformList { Some(self.id.clone()) } - fn initialize( - &mut self, - view_state: &mut V, - element_state: Option, - cx: &mut ViewContext, - ) -> Self::ElementState { - if let Some(mut element_state) = element_state { - element_state.interactive = self - .interactivity - .initialize(Some(element_state.interactive), cx); - element_state - } else { - let item_size = self.measure_item(view_state, None, cx); - UniformListState { - interactive: self.interactivity.initialize(None, cx), - item_size, - } - } - } - fn layout( &mut self, - _view_state: &mut V, + view_state: &mut V, element_state: Option, cx: &mut ViewContext, ) -> (LayoutId, Self::ElementState) { let max_items = self.item_count; - let item_size = element_state.item_size; let rem_size = cx.rem_size(); + let item_size = element_state + .as_ref() + .map(|s| s.item_size) + .unwrap_or_else(|| self.measure_item(view_state, None, cx)); - self.interactivity - .layout(&mut element_state.interactive, cx, |style, cx| { - cx.request_measured_layout( - style, - rem_size, - move |known_dimensions: Size>, - available_space: Size| { - let desired_height = item_size.height * max_items; - let width = known_dimensions - .width - .unwrap_or(match available_space.width { - AvailableSpace::Definite(x) => x, + let (layout_id, interactive) = + self.interactivity + .layout(element_state.map(|s| s.interactive), cx, |style, cx| { + cx.request_measured_layout( + style, + rem_size, + move |known_dimensions: Size>, + available_space: Size| { + let desired_height = item_size.height * max_items; + let width = + known_dimensions + .width + .unwrap_or(match available_space.width { + AvailableSpace::Definite(x) => x, + AvailableSpace::MinContent | AvailableSpace::MaxContent => { + item_size.width + } + }); + let height = match available_space.height { + AvailableSpace::Definite(x) => desired_height.min(x), AvailableSpace::MinContent | AvailableSpace::MaxContent => { - item_size.width + desired_height } - }); - let height = match available_space.height { - AvailableSpace::Definite(x) => desired_height.min(x), - AvailableSpace::MinContent | AvailableSpace::MaxContent => { - desired_height - } - }; - size(width, height) - }, - ) - }) + }; + size(width, height) + }, + ) + }); + + let element_state = UniformListState { + interactive, + item_size, + }; + + (layout_id, element_state) } fn paint( diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index 1ce1c4d34916b41202e8ff407c3f6993b25b67c7..c6ae9240abc130ce48884f50ceff1f19fdd19c94 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -225,10 +225,10 @@ impl Element for AnyView { fn layout( &mut self, _view_state: &mut ParentViewState, - rendered_element: Option, + _element_state: Option, cx: &mut ViewContext, ) -> (LayoutId, Self::ElementState) { - (self.layout)(self, rendered_element, cx) + (self.layout)(self, cx) } fn paint( diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 9c1951287124113c4b3934b314a5838dc2df2613..2f223e8314897e4fb92a38d8b02c4835fe84e4d0 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1076,26 +1076,22 @@ impl<'a> WindowContext<'a> { self.with_z_index(0, |cx| { let available_space = cx.window.viewport_size.map(Into::into); - root_view.draw(available_space, cx); + root_view.draw(Point::zero(), available_space, cx); }); if let Some(active_drag) = self.app.active_drag.take() { self.with_z_index(1, |cx| { let offset = cx.mouse_position() - active_drag.cursor_offset; - cx.with_element_offset(offset, |cx| { - let available_space = - size(AvailableSpace::MinContent, AvailableSpace::MinContent); - active_drag.view.draw(available_space, cx); - cx.active_drag = Some(active_drag); - }); + let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent); + active_drag.view.draw(offset, available_space, cx); + cx.active_drag = Some(active_drag); }); } else if let Some(active_tooltip) = self.app.active_tooltip.take() { self.with_z_index(1, |cx| { - cx.with_element_offset(active_tooltip.cursor_offset, |cx| { - let available_space = - size(AvailableSpace::MinContent, AvailableSpace::MinContent); - active_tooltip.view.draw(available_space, cx); - }); + let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent); + active_tooltip + .view + .draw(active_tooltip.cursor_offset, available_space, cx); }); } From 4f096333793ad83577769b15a9203560aac67cfd Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 15 Nov 2023 14:17:49 -0700 Subject: [PATCH 3/3] Remove focus_in styling helper --- crates/gpui2/src/elements/div.rs | 14 -------------- crates/storybook2/src/stories/focus.rs | 1 - 2 files changed, 15 deletions(-) diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index 3a3ad5936ebba2ca0567f0e1eb926a708617717a..e098e8ef1aaf184cb3f126fd8df5db06d8942089 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -437,14 +437,6 @@ pub trait FocusableComponent: InteractiveComponent { self } - fn focus_in(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self - where - Self: Sized, - { - self.interactivity().focus_in_style = f(StyleRefinement::default()); - self - } - fn in_focus(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self where Self: Sized, @@ -730,7 +722,6 @@ pub struct Interactivity { pub group: Option, pub base_style: StyleRefinement, pub focus_style: StyleRefinement, - pub focus_in_style: StyleRefinement, pub in_focus_style: StyleRefinement, pub hover_style: StyleRefinement, pub group_hover_style: Option, @@ -1113,10 +1104,6 @@ where style.refine(&self.base_style); if let Some(focus_handle) = self.tracked_focus_handle.as_ref() { - if focus_handle.contains_focused(cx) { - style.refine(&self.focus_in_style); - } - if focus_handle.within_focused(cx) { style.refine(&self.in_focus_style); } @@ -1189,7 +1176,6 @@ impl Default for Interactivity { group: None, base_style: StyleRefinement::default(), focus_style: StyleRefinement::default(), - focus_in_style: StyleRefinement::default(), in_focus_style: StyleRefinement::default(), hover_style: StyleRefinement::default(), group_hover_style: None, diff --git a/crates/storybook2/src/stories/focus.rs b/crates/storybook2/src/stories/focus.rs index a8794afdb86053c93d06c73f82cf0af7125deeeb..571882f1f29c92eeed4e8ec56374879280bf27af 100644 --- a/crates/storybook2/src/stories/focus.rs +++ b/crates/storybook2/src/stories/focus.rs @@ -57,7 +57,6 @@ impl Render for FocusStory { .size_full() .bg(color_1) .focus(|style| style.bg(color_2)) - .focus_in(|style| style.bg(color_3)) .child( div() .track_focus(&self.child_1_focus)