From d446b9111727b2ecab5043f337ea0ca7a22c16bb Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Oct 2023 22:10:39 +0200 Subject: [PATCH] Checkpoint --- crates/gpui3/src/elements/div.rs | 82 ++++------------------ crates/gpui3/src/elements/img.rs | 6 +- crates/gpui3/src/elements/svg.rs | 8 +-- crates/gpui3/src/interactive.rs | 113 ++++++++++++++++++++++++------- 4 files changed, 108 insertions(+), 101 deletions(-) diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 27e245bafba1e32518ea3bd90cfe004089fa836b..33dbe156716a4a5e52d1ada9d86103de63ee2949 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/crates/gpui3/src/elements/div.rs @@ -1,10 +1,9 @@ use crate::{ Active, Anonymous, AnyElement, AppContext, BorrowWindow, Bounds, Click, DispatchPhase, Element, ElementFocusability, ElementId, ElementIdentity, Focus, FocusHandle, FocusListeners, Focusable, - GlobalElementId, Hover, Identified, Interactive, InteractiveState, IntoAnyElement, - KeyDownEvent, KeyMatch, LayoutId, MouseClickEvent, MouseDownEvent, MouseMoveEvent, - MouseUpEvent, NonFocusable, Overflow, ParentElement, Pixels, Point, ScrollWheelEvent, - SharedString, Style, StyleRefinement, Styled, ViewContext, + GlobalElementId, Hover, Identified, Interactive, Interactivity, IntoAnyElement, KeyDownEvent, + KeyMatch, LayoutId, MouseDownEvent, MouseMoveEvent, MouseUpEvent, NonFocusable, Overflow, + ParentElement, Pixels, Point, SharedString, Style, StyleRefinement, Styled, ViewContext, }; use collections::HashMap; use parking_lot::Mutex; @@ -68,6 +67,7 @@ pub struct Div< > { identity: I, focusability: F, + interactivity: Interactivity, children: SmallVec<[AnyElement; 2]>, group: Option, base_style: StyleRefinement, @@ -75,7 +75,6 @@ pub struct Div< group_hover: Option, active_style: StyleRefinement, group_active: Option, - interactive_state: InteractiveState, } pub fn div() -> Div @@ -85,6 +84,7 @@ where Div { identity: Anonymous, focusability: NonFocusable, + interactivity: Interactivity::default(), children: SmallVec::new(), group: None, base_style: StyleRefinement::default(), @@ -92,7 +92,6 @@ where group_hover: None, active_style: StyleRefinement::default(), group_active: None, - interactive_state: InteractiveState::default(), } } @@ -110,6 +109,7 @@ where Div { identity: Identified(id.into()), focusability: self.focusability, + interactivity: self.interactivity, children: self.children, group: self.group, base_style: self.base_style, @@ -117,7 +117,6 @@ where group_hover: self.group_hover, active_style: self.active_style, group_active: self.group_active, - interactive_state: self.interactive_state, } } } @@ -268,62 +267,6 @@ where }); } } - - fn paint_event_listeners( - &mut self, - bounds: Bounds, - pending_click: Arc>>, - cx: &mut ViewContext, - ) { - let click_listeners = mem::take(&mut self.interactive_state.mouse_click); - - let mouse_down = pending_click.lock().clone(); - if let Some(mouse_down) = mouse_down { - cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| { - if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { - let mouse_click = MouseClickEvent { - down: mouse_down.clone(), - up: event.clone(), - }; - for listener in &click_listeners { - listener(state, &mouse_click, cx); - } - } - - *pending_click.lock() = None; - }); - } else { - cx.on_mouse_event(move |_state, event: &MouseDownEvent, phase, _cx| { - if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { - *pending_click.lock() = Some(event.clone()); - } - }); - } - - for listener in mem::take(&mut self.interactive_state.mouse_down) { - cx.on_mouse_event(move |state, event: &MouseDownEvent, phase, cx| { - listener(state, event, &bounds, phase, cx); - }) - } - - for listener in mem::take(&mut self.interactive_state.mouse_up) { - cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| { - listener(state, event, &bounds, phase, cx); - }) - } - - for listener in mem::take(&mut self.interactive_state.mouse_move) { - cx.on_mouse_event(move |state, event: &MouseMoveEvent, phase, cx| { - listener(state, event, &bounds, phase, cx); - }) - } - - for listener in mem::take(&mut self.interactive_state.scroll_wheel) { - cx.on_mouse_event(move |state, event: &ScrollWheelEvent, phase, cx| { - listener(state, event, &bounds, phase, cx); - }) - } - } } impl Div @@ -342,7 +285,7 @@ where group_hover: self.group_hover, active_style: self.active_style, group_active: self.group_active, - interactive_state: self.interactive_state, + interactivity: self.interactivity, } } } @@ -395,7 +338,7 @@ where self.with_element_id(cx, |this, global_id, cx| { let element_state = element_state.unwrap_or_default(); - let mut key_listeners = mem::take(&mut this.interactive_state.key); + let mut key_listeners = mem::take(&mut this.interactivity.key); if let Some(global_id) = global_id { key_listeners.push(( TypeId::of::(), @@ -421,7 +364,7 @@ where } }); }); - this.interactive_state.key = key_listeners; + this.interactivity.key = key_listeners; element_state }) @@ -485,7 +428,8 @@ where cx, ); this.focusability.paint(bounds, cx); - this.paint_event_listeners(bounds, element_state.pending_click.clone(), cx); + this.interactivity + .paint(bounds, element_state.pending_click.clone(), cx); }); cx.stack(1, |cx| { @@ -549,8 +493,8 @@ where F: ElementFocusability, V: 'static + Send + Sync, { - fn interactive_state(&mut self) -> &mut InteractiveState { - &mut self.interactive_state + fn interactivity(&mut self) -> &mut Interactivity { + &mut self.interactivity } } diff --git a/crates/gpui3/src/elements/img.rs b/crates/gpui3/src/elements/img.rs index d5db8032d725b2d9a52f25ac767fdf225649ca71..abc6e1f36a62afb6770cf71d6034104edce1e16d 100644 --- a/crates/gpui3/src/elements/img.rs +++ b/crates/gpui3/src/elements/img.rs @@ -1,7 +1,7 @@ use crate::{ div, Active, Anonymous, AnyElement, BorrowWindow, Bounds, Click, Div, DivState, Element, ElementFocusability, ElementId, ElementIdentity, Focus, FocusListeners, Focusable, Hover, - Identified, Interactive, InteractiveState, IntoAnyElement, LayoutId, NonFocusable, Pixels, + Identified, Interactive, Interactivity, IntoAnyElement, LayoutId, NonFocusable, Pixels, SharedString, StyleRefinement, Styled, ViewContext, }; use futures::FutureExt; @@ -156,8 +156,8 @@ where I: ElementIdentity, F: ElementFocusability, { - fn interactive_state(&mut self) -> &mut InteractiveState { - self.base.interactive_state() + fn interactivity(&mut self) -> &mut Interactivity { + self.base.interactivity() } } diff --git a/crates/gpui3/src/elements/svg.rs b/crates/gpui3/src/elements/svg.rs index b3d8c66b19023dd593c4fdedd5c1f117dfe414d9..7ed328a95f94dc00a723f84fd5cd998143c6eef9 100644 --- a/crates/gpui3/src/elements/svg.rs +++ b/crates/gpui3/src/elements/svg.rs @@ -1,8 +1,8 @@ use crate::{ div, Active, Anonymous, AnyElement, Bounds, Click, Div, DivState, Element, ElementFocusability, ElementId, ElementIdentity, Focus, FocusListeners, Focusable, Hover, Identified, Interactive, - InteractiveState, IntoAnyElement, LayoutId, NonFocusable, Pixels, SharedString, - StyleRefinement, Styled, ViewContext, + Interactivity, IntoAnyElement, LayoutId, NonFocusable, Pixels, SharedString, StyleRefinement, + Styled, ViewContext, }; use util::ResultExt; @@ -130,8 +130,8 @@ where I: ElementIdentity, F: ElementFocusability, { - fn interactive_state(&mut self) -> &mut InteractiveState { - self.base.interactive_state() + fn interactivity(&mut self) -> &mut Interactivity { + self.base.interactivity() } } diff --git a/crates/gpui3/src/interactive.rs b/crates/gpui3/src/interactive.rs index d67a5d75787348cf6de01a8e6e0c105558affe53..9baae220ae04cd6b56356d00c127a7d15b7b0c27 100644 --- a/crates/gpui3/src/interactive.rs +++ b/crates/gpui3/src/interactive.rs @@ -1,3 +1,4 @@ +use parking_lot::Mutex; use smallvec::SmallVec; use crate::{ @@ -6,12 +7,13 @@ use crate::{ }; use std::{ any::{Any, TypeId}, + mem, ops::Deref, sync::Arc, }; pub trait Interactive: Element { - fn interactive_state(&mut self) -> &mut InteractiveState; + fn interactivity(&mut self) -> &mut Interactivity; fn on_mouse_down( mut self, @@ -24,16 +26,16 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().mouse_down.push(Arc::new( - move |view, event, bounds, phase, cx| { + self.interactivity() + .mouse_down + .push(Arc::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && event.button == button && bounds.contains_point(&event.position) { handler(view, event, cx) } - }, - )); + })); self } @@ -48,7 +50,7 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state() + self.interactivity() .mouse_up .push(Arc::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble @@ -72,16 +74,16 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().mouse_down.push(Arc::new( - move |view, event, bounds, phase, cx| { + self.interactivity() + .mouse_down + .push(Arc::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Capture && event.button == button && !bounds.contains_point(&event.position) { handler(view, event, cx) } - }, - )); + })); self } @@ -96,7 +98,7 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state() + self.interactivity() .mouse_up .push(Arc::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Capture @@ -119,13 +121,13 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().mouse_move.push(Arc::new( - move |view, event, bounds, phase, cx| { + self.interactivity() + .mouse_move + .push(Arc::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { handler(view, event, cx); } - }, - )); + })); self } @@ -139,13 +141,13 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().scroll_wheel.push(Arc::new( - move |view, event, bounds, phase, cx| { + self.interactivity() + .scroll_wheel + .push(Arc::new(move |view, event, bounds, phase, cx| { if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { handler(view, event, cx); } - }, - )); + })); self } @@ -163,7 +165,7 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().key.push(( + self.interactivity().key.push(( TypeId::of::(), Arc::new(move |view, event, _, phase, cx| { let event = event.downcast_ref().unwrap(); @@ -184,7 +186,7 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().key.push(( + self.interactivity().key.push(( TypeId::of::(), Arc::new(move |view, event, _, phase, cx| { let event = event.downcast_ref().unwrap(); @@ -205,7 +207,7 @@ pub trait Interactive: Element { where Self: Sized, { - self.interactive_state().key.push(( + self.interactivity().key.push(( TypeId::of::(), Arc::new(move |view, event, _, phase, cx| { let event = event.downcast_ref().unwrap(); @@ -228,7 +230,7 @@ pub trait Click: Interactive { where Self: Sized, { - self.interactive_state() + self.interactivity() .mouse_click .push(Arc::new(move |view, event, cx| handler(view, event, cx))); self @@ -494,7 +496,7 @@ pub type KeyListener = Arc< + 'static, >; -pub struct InteractiveState { +pub struct Interactivity { pub mouse_down: SmallVec<[MouseDownListener; 2]>, pub mouse_up: SmallVec<[MouseUpListener; 2]>, pub mouse_click: SmallVec<[MouseClickListener; 2]>, @@ -503,7 +505,7 @@ pub struct InteractiveState { pub key: SmallVec<[(TypeId, KeyListener); 32]>, } -impl Default for InteractiveState { +impl Default for Interactivity { fn default() -> Self { Self { mouse_down: SmallVec::new(), @@ -515,3 +517,64 @@ impl Default for InteractiveState { } } } + +impl Interactivity +where + V: 'static + Send + Sync, +{ + pub fn paint( + &mut self, + bounds: Bounds, + pending_click: Arc>>, + cx: &mut ViewContext, + ) { + let click_listeners = mem::take(&mut self.mouse_click); + + let mouse_down = pending_click.lock().clone(); + if let Some(mouse_down) = mouse_down { + cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| { + if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { + let mouse_click = MouseClickEvent { + down: mouse_down.clone(), + up: event.clone(), + }; + for listener in &click_listeners { + listener(state, &mouse_click, cx); + } + } + + *pending_click.lock() = None; + }); + } else { + cx.on_mouse_event(move |_state, event: &MouseDownEvent, phase, _cx| { + if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) { + *pending_click.lock() = Some(event.clone()); + } + }); + } + + for listener in mem::take(&mut self.mouse_down) { + cx.on_mouse_event(move |state, event: &MouseDownEvent, phase, cx| { + listener(state, event, &bounds, phase, cx); + }) + } + + for listener in mem::take(&mut self.mouse_up) { + cx.on_mouse_event(move |state, event: &MouseUpEvent, phase, cx| { + listener(state, event, &bounds, phase, cx); + }) + } + + for listener in mem::take(&mut self.mouse_move) { + cx.on_mouse_event(move |state, event: &MouseMoveEvent, phase, cx| { + listener(state, event, &bounds, phase, cx); + }) + } + + for listener in mem::take(&mut self.scroll_wheel) { + cx.on_mouse_event(move |state, event: &ScrollWheelEvent, phase, cx| { + listener(state, event, &bounds, phase, cx); + }) + } + } +}