Get basic mouse_down and mouse_up working

This commit is contained in:
Nathan Sobo 2023-08-16 22:21:27 -06:00
parent 187d78011c
commit 812d3f6af6
10 changed files with 175 additions and 82 deletions

View file

@ -4,7 +4,7 @@ use crate::{
text::ArcCow,
themes::rose_pine,
};
use gpui::ViewContext;
use gpui::{platform::MouseButton, ViewContext};
use playground_macros::Element;
use std::{marker::PhantomData, rc::Rc};
@ -69,7 +69,7 @@ impl<V: 'static, D: 'static> Button<V, D> {
pub fn click(self, handler: impl Fn(&mut V, &D, &mut ViewContext<V>) + 'static) -> Self {
let data = self.data.clone();
Element::left_click(self, move |view, _, cx| {
Element::click(self, MouseButton::Left, move |view, _, cx| {
handler(view, data.as_ref(), cx);
})
}
@ -89,7 +89,9 @@ impl<V: 'static, D: 'static> Button<V, D> {
if let Some(handler) = self.handlers.click.clone() {
let data = self.data.clone();
button.left_click(move |view, event, cx| handler(view, data.as_ref(), cx))
button.mouse_down(MouseButton::Left, move |view, event, cx| {
handler(view, data.as_ref(), cx)
})
} else {
button
}

View file

@ -7,12 +7,12 @@ use anyhow::Result;
pub use gpui::LayoutContext;
use gpui::{
geometry::{DefinedLength, Length},
platform::MouseButton,
scene::MouseClick,
EngineLayout, RenderContext, ViewContext, WindowContext,
platform::{MouseButton, MouseButtonEvent},
EngineLayout, EventContext, RenderContext, ViewContext,
};
use playground_macros::tailwind_lengths;
use std::{any::Any, rc::Rc};
use smallvec::SmallVec;
use std::{any::Any, cell::Cell, rc::Rc};
pub use crate::paint_context::PaintContext;
pub use taffy::tree::NodeId;
@ -23,7 +23,7 @@ pub struct Layout<'a, E: ?Sized> {
}
pub struct ElementHandlers<V> {
click: Option<Rc<dyn Fn(&mut V, MouseClick, &mut WindowContext, usize)>>,
mouse_button: SmallVec<[Rc<dyn Fn(&mut V, &MouseButtonEvent, &mut EventContext<V>)>; 2]>,
}
pub struct ElementMetadata<V> {
@ -42,7 +42,9 @@ impl<V> Default for ElementMetadata<V> {
impl<V> Default for ElementHandlers<V> {
fn default() -> Self {
ElementHandlers { click: None }
ElementHandlers {
mouse_button: Default::default(),
}
}
}
@ -79,36 +81,62 @@ pub trait Element<V: 'static>: 'static {
Adapter(self.into_any())
}
fn left_click(self, handler: impl Fn(&mut V, MouseClick, &mut ViewContext<V>) + 'static) -> Self
where
Self: Sized,
{
self.click(MouseButton::Left, handler)
}
fn right_click(
fn click(
self,
handler: impl Fn(&mut V, MouseClick, &mut ViewContext<V>) + 'static,
button: MouseButton,
handler: impl Fn(&mut V, &MouseButtonEvent, &mut ViewContext<V>) + 'static,
) -> Self
where
Self: Sized,
{
self.click(MouseButton::Right, handler)
let pressed: Rc<Cell<bool>> = Default::default();
self.mouse_down(button, {
let pressed = pressed.clone();
move |_, _, _| {
pressed.set(true);
}
})
.mouse_up(button, move |view, event, event_cx| {
if pressed.get() {
pressed.set(false);
handler(view, event, event_cx);
}
})
}
fn click(
fn mouse_down(
mut self,
button: MouseButton,
handler: impl Fn(&mut V, MouseClick, &mut ViewContext<V>) + 'static,
handler: impl Fn(&mut V, &MouseButtonEvent, &mut EventContext<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.handlers_mut()
.mouse_button
.push(Rc::new(move |view, event, event_cx| {
if event.button == button && event.is_down {
handler(view, event, event_cx);
}
}));
self
}
fn mouse_up(
mut self,
button: MouseButton,
handler: impl Fn(&mut V, &MouseButtonEvent, &mut EventContext<V>) + 'static,
) -> Self
where
Self: Sized,
{
self.handlers_mut()
.mouse_button
.push(Rc::new(move |view, event, event_cx| {
if event.button == button && !event.is_down {
handler(view, event, event_cx);
}
}));
self
}
@ -385,7 +413,7 @@ pub struct AnyElement<V> {
layout: Option<(NodeId, Box<dyn Any>)>,
}
impl<V> AnyElement<V> {
impl<V: 'static> AnyElement<V> {
pub fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId> {
let pushed_text_style = self.push_text_style(cx);
@ -426,7 +454,20 @@ impl<V> AnyElement<V> {
from_element: element_layout.as_mut(),
};
if let Some(click_handler) = self.element.handlers_mut().click.clone() {}
for handler in self.element.handlers_mut().mouse_button.iter().cloned() {
let EngineLayout { order, bounds } = layout.from_engine;
let view_id = cx.view_id();
cx.draw_interactive_region(
order,
bounds,
move |view, event: &MouseButtonEvent, window_cx| {
let mut view_cx = ViewContext::mutable(window_cx, view_id);
let mut event_cx = EventContext::new(&mut view_cx);
(handler)(view, event, &mut event_cx);
},
);
}
self.element.paint(layout, view, cx)?;
if pushed_text_style {

View file

@ -1,11 +1,9 @@
use std::{
any::{Any, TypeId},
collections::BTreeSet,
rc::Rc,
};
use std::{any::TypeId, rc::Rc};
use derive_more::{Deref, DerefMut};
use gpui::{geometry::rect::RectF, EventContext, RenderContext, ViewContext, WindowContext};
use gpui::{
geometry::rect::RectF, scene::InteractiveRegion, EventContext, RenderContext, ViewContext,
};
pub use gpui::{LayoutContext, PaintContext as LegacyPaintContext};
pub use taffy::tree::NodeId;
@ -15,7 +13,6 @@ pub struct PaintContext<'a, 'b, 'c, 'd, V> {
#[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> {
@ -37,20 +34,17 @@ impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> {
legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>,
scene: &'d mut gpui::SceneBuilder,
) -> Self {
Self {
legacy_cx,
scene,
regions: BTreeSet::new(),
}
Self { legacy_cx, scene }
}
pub fn paint_interactive<E: 'static>(
pub fn draw_interactive_region<E: 'static>(
&mut self,
order: u32,
bounds: RectF,
handler: impl Fn(&mut V, E, &mut EventContext<V>) + 'static,
handler: impl Fn(&mut V, &E, &mut EventContext<V>) + 'static,
) {
self.regions.insert(InteractiveRegion {
// We'll sort these by their order in `take_interactive_regions`.
self.scene.interactive_regions.push(InteractiveRegion {
order,
bounds,
event_handler: Rc::new(move |view, event, window_cx, view_id| {
@ -58,38 +52,12 @@ impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> {
let mut cx = EventContext::new(&mut cx);
handler(
view.downcast_mut().unwrap(),
*event.downcast().unwrap(),
event.downcast_ref().unwrap(),
&mut cx,
)
}),
event_type: TypeId::of::<E>(),
view_id: self.view_id(),
});
}
}
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)
}
}

View file

@ -5,7 +5,7 @@ use element::Element;
use frame::frame;
use gpui::{
geometry::{rect::RectF, vector::vec2f},
platform::WindowOptions,
platform::{MouseButton, WindowOptions},
};
use log::LevelFilter;
use simplelog::SimpleLogger;
@ -49,7 +49,12 @@ 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")
.mouse_up(MouseButton::Left, |_, _, _| (println!("up!")))
.mouse_down(MouseButton::Left, |_, _, _| (println!("down!"))),
)
}
// todo!()