layout_context.rs

 1use anyhow::{anyhow, Result};
 2use derive_more::{Deref, DerefMut};
 3use gpui::{geometry::Size, MeasureParams, RenderContext, ViewContext};
 4pub use gpui::{taffy::tree::NodeId, LayoutContext as LegacyLayoutContext};
 5
 6use crate::{element::Layout, style::Style};
 7
 8#[derive(Deref, DerefMut)]
 9pub struct LayoutContext<'a, 'b, 'c, 'd, V> {
10    #[deref]
11    #[deref_mut]
12    pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>,
13}
14
15impl<'a, 'b, V> RenderContext<'a, 'b, V> for LayoutContext<'a, 'b, '_, '_, V> {
16    fn text_style(&self) -> gpui::fonts::TextStyle {
17        self.legacy_cx.text_style()
18    }
19
20    fn push_text_style(&mut self, style: gpui::fonts::TextStyle) {
21        self.legacy_cx.push_text_style(style)
22    }
23
24    fn pop_text_style(&mut self) {
25        self.legacy_cx.pop_text_style()
26    }
27
28    fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
29        &mut self.view_context
30    }
31}
32
33impl<'a, 'b, 'c, 'd, V: 'static> LayoutContext<'a, 'b, 'c, 'd, V> {
34    pub fn new(legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>) -> Self {
35        Self { legacy_cx }
36    }
37
38    pub fn add_layout_node<D>(
39        &mut self,
40        style: Style,
41        element_data: D,
42        children: impl IntoIterator<Item = NodeId>,
43    ) -> Result<Layout<V, D>> {
44        let rem_size = self.rem_pixels();
45        let id = self
46            .legacy_cx
47            .layout_engine()
48            .ok_or_else(|| anyhow!("no layout engine"))?
49            .add_node(style.to_taffy(rem_size), children)?;
50
51        Ok(Layout::new(id, element_data))
52    }
53
54    pub fn add_measured_layout_node<D, F>(
55        &mut self,
56        style: Style,
57        element_data: D,
58        measure: F,
59    ) -> Result<Layout<V, D>>
60    where
61        F: Fn(MeasureParams) -> Size<f32> + Sync + Send + 'static,
62    {
63        let rem_size = self.rem_pixels();
64        let layout_id = self
65            .layout_engine()
66            .ok_or_else(|| anyhow!("no layout engine"))?
67            .add_measured_node(style.to_taffy(rem_size), measure)?;
68
69        Ok(Layout::new(layout_id, element_data))
70    }
71}