1use anyhow::{anyhow, Result};
2use derive_more::{Deref, DerefMut};
3use gpui::{scene::EventHandler, EngineLayout, EventContext, LayoutId, RenderContext, ViewContext};
4pub use gpui::{LayoutContext, PaintContext as LegacyPaintContext};
5use std::{any::TypeId, rc::Rc};
6pub use taffy::tree::NodeId;
7
8#[derive(Deref, DerefMut)]
9pub struct PaintContext<'a, 'b, 'c, 'd, V> {
10 #[deref]
11 #[deref_mut]
12 pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>,
13 pub(crate) scene: &'d mut gpui::SceneBuilder,
14}
15
16impl<'a, 'b, V> RenderContext<'a, 'b, V> for PaintContext<'a, 'b, '_, '_, V> {
17 fn text_style(&self) -> gpui::fonts::TextStyle {
18 self.legacy_cx.text_style()
19 }
20
21 fn push_text_style(&mut self, style: gpui::fonts::TextStyle) {
22 self.legacy_cx.push_text_style(style)
23 }
24
25 fn pop_text_style(&mut self) {
26 self.legacy_cx.pop_text_style()
27 }
28
29 fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
30 &mut self.view_context
31 }
32}
33
34impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> {
35 pub fn new(
36 legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>,
37 scene: &'d mut gpui::SceneBuilder,
38 ) -> Self {
39 Self { legacy_cx, scene }
40 }
41
42 pub fn on_event<E: 'static>(
43 &mut self,
44 order: u32,
45 handler: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
46 ) {
47 let view = self.weak_handle();
48
49 self.scene.event_handlers.push(EventHandler {
50 order,
51 handler: Rc::new(move |event, window_cx| {
52 if let Some(view) = view.upgrade(window_cx) {
53 view.update(window_cx, |view, view_cx| {
54 let mut event_cx = EventContext::new(view_cx);
55 handler(view, event.downcast_ref().unwrap(), &mut event_cx);
56 event_cx.bubble
57 })
58 } else {
59 true
60 }
61 }),
62 event_type: TypeId::of::<E>(),
63 })
64 }
65
66 pub(crate) fn computed_layout(&mut self, layout_id: LayoutId) -> Result<EngineLayout> {
67 self.layout_engine()
68 .ok_or_else(|| anyhow!("no layout engine present"))?
69 .computed_layout(layout_id)
70 }
71}