From 5243401afae05aea5f86f82c8ae28db092c72850 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 30 Nov 2023 17:12:40 +0100 Subject: [PATCH] Pass a `WindowContext` in `request_measured_layout` Co-Authored-By: Nathan Sobo --- crates/gpui2/src/elements/text.rs | 6 ++--- crates/gpui2/src/elements/uniform_list.rs | 3 +-- crates/gpui2/src/taffy.rs | 28 ++++++++++++++++------- crates/gpui2/src/view.rs | 4 +--- crates/gpui2/src/window.rs | 27 ++++++++++++++-------- 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index 2f432bcb7540fa7dc8437eecfb61b861eaa9144a..490d0b61a1a5f0e0fdddb374d2a3cb788a49a99d 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -144,7 +144,6 @@ impl TextState { runs: Option>, cx: &mut WindowContext, ) -> LayoutId { - 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()); let line_height = text_style @@ -161,7 +160,7 @@ impl TextState { let layout_id = cx.request_measured_layout(Default::default(), { let element_state = self.clone(); - move |known_dimensions, available_space| { + move |known_dimensions, available_space, cx| { let wrap_width = if text_style.white_space == WhiteSpace::Normal { known_dimensions.width.or(match available_space.width { crate::AvailableSpace::Definite(x) => Some(x), @@ -179,7 +178,8 @@ impl TextState { } } - let Some(lines) = text_system + let Some(lines) = cx + .text_system() .shape_text( &text, font_size, &runs, wrap_width, // Wrap if we know the width. ) diff --git a/crates/gpui2/src/elements/uniform_list.rs b/crates/gpui2/src/elements/uniform_list.rs index ed29caa43d3d938d47d42b66ce4178e38cb13668..d8f4cc6804788d6f06e379321a79ef50c9fbd4d0 100644 --- a/crates/gpui2/src/elements/uniform_list.rs +++ b/crates/gpui2/src/elements/uniform_list.rs @@ -119,8 +119,7 @@ impl Element for UniformList { .layout(state.map(|s| s.interactive), cx, |style, cx| { cx.request_measured_layout( style, - move |known_dimensions: Size>, - available_space: Size| { + move |known_dimensions, available_space, _cx| { let desired_height = item_size.height * max_items; let width = known_dimensions diff --git a/crates/gpui2/src/taffy.rs b/crates/gpui2/src/taffy.rs index 7e25b5c5b2bce8f471d04b02f13e80fd53b586ef..2bceb1bc139be7af1aedc67827da582f319bfc87 100644 --- a/crates/gpui2/src/taffy.rs +++ b/crates/gpui2/src/taffy.rs @@ -1,4 +1,7 @@ -use super::{AbsoluteLength, Bounds, DefiniteLength, Edges, Length, Pixels, Point, Size, Style}; +use crate::{ + AbsoluteLength, Bounds, DefiniteLength, Edges, Length, Pixels, Point, Size, Style, + WindowContext, +}; use collections::{HashMap, HashSet}; use smallvec::SmallVec; use std::fmt::Debug; @@ -16,7 +19,13 @@ pub struct TaffyLayoutEngine { computed_layouts: HashSet, nodes_to_measure: HashMap< LayoutId, - Box>, Size) -> Size>, + Box< + dyn FnMut( + Size>, + Size, + &mut WindowContext, + ) -> Size, + >, >, } @@ -69,7 +78,8 @@ impl TaffyLayoutEngine { &mut self, style: Style, rem_size: Pixels, - measure: impl FnMut(Size>, Size) -> Size + 'static, + measure: impl FnMut(Size>, Size, &mut WindowContext) -> Size + + 'static, ) -> LayoutId { let style = style.to_taffy(rem_size); @@ -129,7 +139,12 @@ impl TaffyLayoutEngine { Ok(edges) } - pub fn compute_layout(&mut self, id: LayoutId, available_space: Size) { + pub fn compute_layout( + &mut self, + id: LayoutId, + available_space: Size, + cx: &mut WindowContext, + ) { // Leaving this here until we have a better instrumentation approach. // println!("Laying out {} children", self.count_all_children(id)?); // println!("Max layout depth: {}", self.max_depth(0, id)?); @@ -158,8 +173,6 @@ impl TaffyLayoutEngine { } // let started_at = std::time::Instant::now(); - dbg!(">>>>>>>>>>>>>"); - self.taffy .compute_layout_with_measure( id.into(), @@ -174,12 +187,11 @@ impl TaffyLayoutEngine { height: known_dimensions.height.map(Pixels), }; - measure(known_dimensions, available_space.into()).into() + measure(known_dimensions, available_space.into(), cx).into() }, ) .expect(EXPECT_MESSAGE); - dbg!("<<<<<<"); // println!("compute_layout took {:?}", started_at.elapsed()); } diff --git a/crates/gpui2/src/view.rs b/crates/gpui2/src/view.rs index f31b0ae753c2a759a776857658c925eb34787dee..6e1d59fc5ab17871c3c58de5c62d0b16ec9fe15d 100644 --- a/crates/gpui2/src/view.rs +++ b/crates/gpui2/src/view.rs @@ -209,9 +209,7 @@ impl AnyView { ) { cx.with_absolute_element_offset(origin, |cx| { let (layout_id, rendered_element) = (self.layout)(self, cx); - cx.window - .layout_engine - .compute_layout(layout_id, available_space); + cx.compute_layout(layout_id, available_space); (self.paint)(self, rendered_element, cx); }) } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 6f0d1381d064778a0cc326cefc43a5491145b655..d706787da8d8c50449d0c2279ad62bd4d67a8365 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -209,7 +209,7 @@ pub struct Window { sprite_atlas: Arc, rem_size: Pixels, viewport_size: Size, - pub(crate) layout_engine: TaffyLayoutEngine, + layout_engine: Option, pub(crate) root_view: Option, pub(crate) element_id_stack: GlobalElementId, pub(crate) previous_frame: Frame, @@ -327,7 +327,7 @@ impl Window { sprite_atlas, rem_size: px(16.), viewport_size: content_size, - layout_engine: TaffyLayoutEngine::new(), + layout_engine: Some(TaffyLayoutEngine::new()), root_view: None, element_id_stack: GlobalElementId::default(), previous_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())), @@ -606,9 +606,11 @@ impl<'a> WindowContext<'a> { self.app.layout_id_buffer.extend(children.into_iter()); let rem_size = self.rem_size(); - self.window - .layout_engine - .request_layout(style, rem_size, &self.app.layout_id_buffer) + self.window.layout_engine.as_mut().unwrap().request_layout( + style, + rem_size, + &self.app.layout_id_buffer, + ) } /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children, @@ -618,7 +620,8 @@ impl<'a> WindowContext<'a> { /// The given closure is invoked at layout time with the known dimensions and available space and /// returns a `Size`. pub fn request_measured_layout< - F: FnMut(Size>, Size) -> Size + 'static, + F: FnMut(Size>, Size, &mut WindowContext) -> Size + + 'static, >( &mut self, style: Style, @@ -627,13 +630,15 @@ impl<'a> WindowContext<'a> { let rem_size = self.rem_size(); self.window .layout_engine + .as_mut() + .unwrap() .request_measured_layout(style, rem_size, measure) } pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size) { - self.window - .layout_engine - .compute_layout(layout_id, available_space) + let mut layout_engine = self.window.layout_engine.take().unwrap(); + layout_engine.compute_layout(layout_id, available_space, self); + self.window.layout_engine = Some(layout_engine); } /// Obtain the bounds computed for the given LayoutId relative to the window. This method should not @@ -643,6 +648,8 @@ impl<'a> WindowContext<'a> { let mut bounds = self .window .layout_engine + .as_mut() + .unwrap() .layout_bounds(layout_id) .map(Into::into); bounds.origin += self.element_offset(); @@ -1189,7 +1196,7 @@ impl<'a> WindowContext<'a> { self.text_system().start_frame(); let window = &mut *self.window; - window.layout_engine.clear(); + window.layout_engine.as_mut().unwrap().clear(); mem::swap(&mut window.previous_frame, &mut window.current_frame); let frame = &mut window.current_frame;