use std::{any::TypeId, rc::Rc}; use crate::{element::LayoutId, style::Style}; use anyhow::{anyhow, Result}; use derive_more::{Deref, DerefMut}; use gpui::{geometry::Size, scene::EventHandler, EventContext, Layout, MeasureParams}; pub use gpui::{taffy::tree::NodeId, ViewContext as LegacyViewContext}; #[derive(Deref, DerefMut)] pub struct ViewContext<'a, 'b, 'c, V> { #[deref] #[deref_mut] pub(crate) legacy_cx: &'c mut LegacyViewContext<'a, 'b, V>, } impl<'a, 'b, 'c, V: 'static> ViewContext<'a, 'b, 'c, V> { pub fn new(legacy_cx: &'c mut LegacyViewContext<'a, 'b, V>) -> Self { Self { legacy_cx } } pub fn add_layout_node( &mut self, style: Style, children: impl IntoIterator, ) -> Result { let rem_size = self.rem_size(); let style = style.to_taffy(rem_size); let id = self .legacy_cx .layout_engine() .ok_or_else(|| anyhow!("no layout engine"))? .add_node(style, children)?; Ok(id) } pub fn add_measured_layout_node(&mut self, style: Style, measure: F) -> Result where F: Fn(MeasureParams) -> Size + Sync + Send + 'static, { let rem_size = self.rem_size(); let layout_id = self .layout_engine() .ok_or_else(|| anyhow!("no layout engine"))? .add_measured_node(style.to_taffy(rem_size), measure)?; Ok(layout_id) } pub fn on_event( &mut self, order: u32, handler: impl Fn(&mut V, &E, &mut EventContext) + 'static, ) { let view = self.weak_handle(); self.scene().event_handlers.push(EventHandler { order, handler: Rc::new(move |event, window_cx| { if let Some(view) = view.upgrade(window_cx) { view.update(window_cx, |view, view_cx| { let mut event_cx = EventContext::new(view_cx); handler(view, event.downcast_ref().unwrap(), &mut event_cx); event_cx.bubble }) } else { true } }), event_type: TypeId::of::(), }) } pub(crate) fn computed_layout(&mut self, layout_id: LayoutId) -> Result { self.layout_engine() .ok_or_else(|| anyhow!("no layout engine present"))? .computed_layout(layout_id) } }