From 187d78011c72a3eecd6216904216855a9e68bcaa Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 16 Aug 2023 13:52:42 -0600 Subject: [PATCH] WIP --- crates/gpui/playground/src/adapter.rs | 2 +- crates/gpui/playground/src/components.rs | 10 +-- crates/gpui/playground/src/element.rs | 61 +++++++------ crates/gpui/playground/src/paint_context.rs | 95 +++++++++++++++++++++ crates/gpui/playground/src/playground.rs | 3 +- crates/gpui/src/app.rs | 6 +- crates/gpui/src/scene.rs | 1 + crates/gpui/src/scene/region.rs | 7 ++ 8 files changed, 147 insertions(+), 38 deletions(-) create mode 100644 crates/gpui/playground/src/paint_context.rs create mode 100644 crates/gpui/src/scene/region.rs diff --git a/crates/gpui/playground/src/adapter.rs b/crates/gpui/playground/src/adapter.rs index b66a176231d299cea4b50d699404e2a2852ce8b0..13548644b558949d6e1fed7f2c70ef20989ddc9a 100644 --- a/crates/gpui/playground/src/adapter.rs +++ b/crates/gpui/playground/src/adapter.rs @@ -38,7 +38,7 @@ impl gpui::Element for Adapter { legacy_cx: &mut gpui::PaintContext, ) -> Self::PaintState { legacy_cx.push_layout_engine(layout_engine.take().unwrap()); - let mut cx = PaintContext { legacy_cx, scene }; + let mut cx = PaintContext::new(legacy_cx, scene); self.0.paint(view, &mut cx).log_err(); *layout_engine = legacy_cx.pop_layout_engine(); debug_assert!(layout_engine.is_some()); diff --git a/crates/gpui/playground/src/components.rs b/crates/gpui/playground/src/components.rs index 780f6bd88ceafacd1b06992637145893fbc7cc77..ba90fcb58f702cc5329219a17416ce1c8ea93994 100644 --- a/crates/gpui/playground/src/components.rs +++ b/crates/gpui/playground/src/components.rs @@ -9,7 +9,7 @@ use playground_macros::Element; use std::{marker::PhantomData, rc::Rc}; struct ButtonHandlers { - click: Option>, + click: Option)>>, } impl Default for ButtonHandlers { @@ -67,10 +67,10 @@ impl Button { self } - pub fn click(self, handler: impl Fn(&mut V, &D) + 'static) -> Self { + pub fn click(self, handler: impl Fn(&mut V, &D, &mut ViewContext) + 'static) -> Self { let data = self.data.clone(); - Element::click(self, move |view, _| { - handler(view, data.as_ref()); + Element::left_click(self, move |view, _, cx| { + handler(view, data.as_ref(), cx); }) } } @@ -89,7 +89,7 @@ impl Button { if let Some(handler) = self.handlers.click.clone() { let data = self.data.clone(); - button.click(move |view, event| handler(view, data.as_ref())) + button.left_click(move |view, event, cx| handler(view, data.as_ref(), cx)) } else { button } diff --git a/crates/gpui/playground/src/element.rs b/crates/gpui/playground/src/element.rs index 03e97b56ea2d6a7f72bf5b9127c2658a1489e1be..78a203a7a96c22d588283b7d11b5a041b73599fe 100644 --- a/crates/gpui/playground/src/element.rs +++ b/crates/gpui/playground/src/element.rs @@ -4,38 +4,18 @@ use crate::{ style::{Display, ElementStyle, Fill, Overflow, Position}, }; use anyhow::Result; -use derive_more::{Deref, DerefMut}; pub use gpui::LayoutContext; use gpui::{ geometry::{DefinedLength, Length}, + platform::MouseButton, scene::MouseClick, - EngineLayout, PaintContext as LegacyPaintContext, RenderContext, + EngineLayout, RenderContext, ViewContext, WindowContext, }; use playground_macros::tailwind_lengths; use std::{any::Any, rc::Rc}; -pub use taffy::tree::NodeId; - -#[derive(Deref, DerefMut)] -pub struct PaintContext<'a, 'b, 'c, 'd, V> { - #[deref] - #[deref_mut] - pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>, - pub(crate) scene: &'d mut gpui::SceneBuilder, -} -impl RenderContext for PaintContext<'_, '_, '_, '_, V> { - fn text_style(&self) -> gpui::fonts::TextStyle { - self.legacy_cx.text_style() - } - - fn push_text_style(&mut self, style: gpui::fonts::TextStyle) { - self.legacy_cx.push_text_style(style) - } - - fn pop_text_style(&mut self) { - self.legacy_cx.pop_text_style() - } -} +pub use crate::paint_context::PaintContext; +pub use taffy::tree::NodeId; pub struct Layout<'a, E: ?Sized> { pub from_engine: EngineLayout, @@ -43,7 +23,7 @@ pub struct Layout<'a, E: ?Sized> { } pub struct ElementHandlers { - click: Option>, + click: Option>, } pub struct ElementMetadata { @@ -99,12 +79,35 @@ pub trait Element: 'static { Adapter(self.into_any()) } - fn click(mut self, handler: impl Fn(&mut V, MouseClick) + 'static) -> Self + fn left_click(self, handler: impl Fn(&mut V, MouseClick, &mut ViewContext) + 'static) -> Self where Self: Sized, { - self.handlers_mut().click = Some(Rc::new(move |view, event| { - handler(view, event); + self.click(MouseButton::Left, handler) + } + + fn right_click( + self, + handler: impl Fn(&mut V, MouseClick, &mut ViewContext) + 'static, + ) -> Self + where + Self: Sized, + { + self.click(MouseButton::Right, handler) + } + + fn click( + mut self, + button: MouseButton, + handler: impl Fn(&mut V, MouseClick, &mut ViewContext) + 'static, + ) -> Self + where + Self: Sized, + { + self.handlers_mut().click = Some(Rc::new(move |view, event, window_cx, view_id| { + if event.button == button { + handler(view, event, &mut ViewContext::mutable(window_cx, view_id)); + } })); self } @@ -423,6 +426,8 @@ impl AnyElement { from_element: element_layout.as_mut(), }; + if let Some(click_handler) = self.element.handlers_mut().click.clone() {} + self.element.paint(layout, view, cx)?; if pushed_text_style { cx.pop_text_style(); diff --git a/crates/gpui/playground/src/paint_context.rs b/crates/gpui/playground/src/paint_context.rs new file mode 100644 index 0000000000000000000000000000000000000000..9190a38d383b0a49dff60f0f178a131eb0ce39ed --- /dev/null +++ b/crates/gpui/playground/src/paint_context.rs @@ -0,0 +1,95 @@ +use std::{ + any::{Any, TypeId}, + collections::BTreeSet, + rc::Rc, +}; + +use derive_more::{Deref, DerefMut}; +use gpui::{geometry::rect::RectF, EventContext, RenderContext, ViewContext, WindowContext}; +pub use gpui::{LayoutContext, PaintContext as LegacyPaintContext}; +pub use taffy::tree::NodeId; + +#[derive(Deref, DerefMut)] +pub struct PaintContext<'a, 'b, 'c, 'd, V> { + #[deref] + #[deref_mut] + pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>, + pub(crate) scene: &'d mut gpui::SceneBuilder, + regions: BTreeSet, +} + +impl RenderContext for PaintContext<'_, '_, '_, '_, V> { + fn text_style(&self) -> gpui::fonts::TextStyle { + self.legacy_cx.text_style() + } + + fn push_text_style(&mut self, style: gpui::fonts::TextStyle) { + self.legacy_cx.push_text_style(style) + } + + fn pop_text_style(&mut self) { + self.legacy_cx.pop_text_style() + } +} + +impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> { + pub fn new( + legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>, + scene: &'d mut gpui::SceneBuilder, + ) -> Self { + Self { + legacy_cx, + scene, + regions: BTreeSet::new(), + } + } + + pub fn paint_interactive( + &mut self, + order: u32, + bounds: RectF, + handler: impl Fn(&mut V, E, &mut EventContext) + 'static, + ) { + self.regions.insert(InteractiveRegion { + order, + bounds, + event_handler: Rc::new(move |view, event, window_cx, view_id| { + let mut cx = ViewContext::mutable(window_cx, view_id); + let mut cx = EventContext::new(&mut cx); + handler( + view.downcast_mut().unwrap(), + *event.downcast().unwrap(), + &mut cx, + ) + }), + event_type: TypeId::of::(), + }); + } +} + +struct InteractiveRegion { + order: u32, + bounds: RectF, + event_handler: Rc, &mut WindowContext, usize)>, + event_type: TypeId, +} + +impl Eq for InteractiveRegion {} + +impl PartialEq for InteractiveRegion { + fn eq(&self, other: &Self) -> bool { + self.order == other.order + } +} + +impl PartialOrd for InteractiveRegion { + fn partial_cmp(&self, other: &Self) -> Option { + todo!() + } +} + +impl Ord for InteractiveRegion { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.order.cmp(&other.order) + } +} diff --git a/crates/gpui/playground/src/playground.rs b/crates/gpui/playground/src/playground.rs index 702487a8812f7b0497e6b3bb41b7bbb8e2afd48e..2abb368ba8ae7979c06727f30ac4aa150d45eb77 100644 --- a/crates/gpui/playground/src/playground.rs +++ b/crates/gpui/playground/src/playground.rs @@ -18,6 +18,7 @@ mod color; mod components; mod element; mod frame; +mod paint_context; mod style; mod text; mod themes; @@ -48,7 +49,7 @@ fn playground(theme: &ThemeColors) -> impl Element { .h_full() .w_half() .fill(theme.success(0.5)) - .child(button().label("Hello").click(|_, _| (println!("hey!")))) + .child(button().label("Hello").click(|_, _, _| (println!("hey!")))) } // todo!() diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 3c1bee5b0b4d899ed567e0b514d1072e8c31ee42..230f11f22053ea2a0cd6fac995c96dfb4a195c5d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -2879,7 +2879,7 @@ impl<'a, 'b, V> DerefMut for ViewContext<'a, 'b, V> { } impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { - pub(crate) fn mutable(window_context: &'b mut WindowContext<'a>, view_id: usize) -> Self { + pub fn mutable(window_context: &'b mut WindowContext<'a>, view_id: usize) -> Self { Self { window_context: Reference::Mutable(window_context), view_id, @@ -2887,7 +2887,7 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { } } - pub(crate) fn immutable(window_context: &'b WindowContext<'a>, view_id: usize) -> Self { + pub fn immutable(window_context: &'b WindowContext<'a>, view_id: usize) -> Self { Self { window_context: Reference::Immutable(window_context), view_id, @@ -3618,7 +3618,7 @@ pub struct EventContext<'a, 'b, 'c, V> { } impl<'a, 'b, 'c, V> EventContext<'a, 'b, 'c, V> { - pub(crate) fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self { + pub fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self { EventContext { view_context, handled: true, diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index cbc0a9215122d925ac25951995d0835ddf29b13f..593d42cc20ce6e7a714c6dc62345c3e29cb4d7c6 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -1,5 +1,6 @@ mod mouse_event; mod mouse_region; +mod region; #[cfg(debug_assertions)] use collections::HashSet; diff --git a/crates/gpui/src/scene/region.rs b/crates/gpui/src/scene/region.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c1f01f5e6151756eb4df69cd9e049db8cef0006 --- /dev/null +++ b/crates/gpui/src/scene/region.rs @@ -0,0 +1,7 @@ +// use crate::geometry::rect::RectF; +// use crate::WindowContext; + +// struct Region { +// pub bounds: RectF, +// pub click_handler: Option>, +// }