Detailed changes
@@ -38,7 +38,7 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
legacy_cx: &mut gpui::PaintContext<V>,
) -> 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());
@@ -9,7 +9,7 @@ use playground_macros::Element;
use std::{marker::PhantomData, rc::Rc};
struct ButtonHandlers<V, D> {
- click: Option<Rc<dyn Fn(&mut V, &D)>>,
+ click: Option<Rc<dyn Fn(&mut V, &D, &mut ViewContext<V>)>>,
}
impl<V, D> Default for ButtonHandlers<V, D> {
@@ -67,10 +67,10 @@ impl<V: 'static, D: 'static> Button<V, D> {
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<V>) + '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<V: 'static, D: 'static> Button<V, D> {
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
}
@@ -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<V> 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<V> {
- click: Option<Rc<dyn Fn(&mut V, MouseClick)>>,
+ click: Option<Rc<dyn Fn(&mut V, MouseClick, &mut WindowContext, usize)>>,
}
pub struct ElementMetadata<V> {
@@ -99,12 +79,35 @@ pub trait Element<V: 'static>: '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<V>) + '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<V>) + 'static,
+ ) -> Self
+ where
+ Self: Sized,
+ {
+ self.click(MouseButton::Right, handler)
+ }
+
+ fn click(
+ mut self,
+ button: MouseButton,
+ handler: impl Fn(&mut V, MouseClick, &mut ViewContext<V>) + '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<V> AnyElement<V> {
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();
@@ -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<InteractiveRegion>,
+}
+
+impl<V> 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<E: 'static>(
+ &mut self,
+ order: u32,
+ bounds: RectF,
+ handler: impl Fn(&mut V, E, &mut EventContext<V>) + '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::<E>(),
+ });
+ }
+}
+
+struct InteractiveRegion {
+ order: u32,
+ bounds: RectF,
+ event_handler: Rc<dyn Fn(&mut dyn Any, Box<dyn Any>, &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<std::cmp::Ordering> {
+ todo!()
+ }
+}
+
+impl Ord for InteractiveRegion {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.order.cmp(&other.order)
+ }
+}
@@ -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<V: 'static>(theme: &ThemeColors) -> impl Element<V> {
.h_full()
.w_half()
.fill(theme.success(0.5))
- .child(button().label("Hello").click(|_, _| (println!("hey!"))))
+ .child(button().label("Hello").click(|_, _, _| (println!("hey!"))))
}
// todo!()
@@ -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,
@@ -1,5 +1,6 @@
mod mouse_event;
mod mouse_region;
+mod region;
#[cfg(debug_assertions)]
use collections::HashSet;
@@ -0,0 +1,7 @@
+// use crate::geometry::rect::RectF;
+// use crate::WindowContext;
+
+// struct Region {
+// pub bounds: RectF,
+// pub click_handler: Option<Rc<dyn Fn(&dyn Any, MouseEvent, &mut WindowContext)>>,
+// }