mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-18 08:02:27 +00:00
Checkpoint
This commit is contained in:
parent
deb0e57c49
commit
4ce7f059c3
8 changed files with 309 additions and 226 deletions
|
@ -24,35 +24,28 @@ pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
|
|||
);
|
||||
}
|
||||
|
||||
pub trait IdentifiedElement: Element {
|
||||
fn id(&self) -> ElementId {
|
||||
Element::id(self).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deref, DerefMut, Default, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub(crate) struct GlobalElementId(SmallVec<[ElementId; 8]>);
|
||||
|
||||
pub trait ElementKind: 'static + Send + Sync {
|
||||
pub trait ElementIdentity: 'static + Send + Sync {
|
||||
fn id(&self) -> Option<ElementId>;
|
||||
}
|
||||
|
||||
pub struct IdentifiedElementKind(pub(crate) ElementId);
|
||||
pub struct AnonymousElementKind;
|
||||
pub struct IdentifiedElement(pub(crate) ElementId);
|
||||
pub struct AnonymousElement;
|
||||
|
||||
impl ElementKind for IdentifiedElementKind {
|
||||
impl ElementIdentity for IdentifiedElement {
|
||||
fn id(&self) -> Option<ElementId> {
|
||||
Some(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl ElementKind for AnonymousElementKind {
|
||||
impl ElementIdentity for AnonymousElement {
|
||||
fn id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait ParentElement: Element {
|
||||
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]>;
|
||||
fn group_mut(&mut self) -> &mut Option<SharedString>;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{
|
||||
AnonymousElementKind, AnyElement, AppContext, BorrowWindow, Bounds, DispatchPhase, Element,
|
||||
ElementId, ElementKind, IdentifiedElement, IdentifiedElementKind, IntoAnyElement, LayoutId,
|
||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Overflow, Pixels, Point,
|
||||
ScrollWheelEvent, SharedString, Style, StyleRefinement, Styled, ViewContext,
|
||||
AnonymousElement, AnyElement, AppContext, BorrowWindow, Bounds, Clickable, DispatchPhase,
|
||||
Element, ElementId, ElementIdentity, IdentifiedElement, Interactive, IntoAnyElement, LayoutId,
|
||||
MouseClickEvent, MouseDownEvent, MouseEventListeners, MouseMoveEvent, MouseUpEvent, Overflow,
|
||||
Pixels, Point, ScrollWheelEvent, SharedString, Style, StyleRefinement, Styled, ViewContext,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
|
@ -59,12 +59,12 @@ impl ScrollState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn div<S>() -> Div<S, AnonymousElementKind>
|
||||
pub fn div<S>() -> Div<S, AnonymousElement>
|
||||
where
|
||||
S: 'static + Send + Sync,
|
||||
{
|
||||
Div {
|
||||
kind: AnonymousElementKind,
|
||||
kind: AnonymousElement,
|
||||
children: SmallVec::new(),
|
||||
group: None,
|
||||
base_style: StyleRefinement::default(),
|
||||
|
@ -76,7 +76,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Div<V: 'static + Send + Sync, K: ElementKind = AnonymousElementKind> {
|
||||
pub struct Div<V: 'static + Send + Sync, K: ElementIdentity = AnonymousElement> {
|
||||
kind: K,
|
||||
children: SmallVec<[AnyElement<V>; 2]>,
|
||||
group: Option<SharedString>,
|
||||
|
@ -93,13 +93,13 @@ struct GroupStyle {
|
|||
style: StyleRefinement,
|
||||
}
|
||||
|
||||
impl<V> Div<V, AnonymousElementKind>
|
||||
impl<V> Div<V, AnonymousElement>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
{
|
||||
pub fn id(self, id: impl Into<ElementId>) -> Div<V, IdentifiedElementKind> {
|
||||
pub fn id(self, id: impl Into<ElementId>) -> Div<V, IdentifiedElement> {
|
||||
Div {
|
||||
kind: IdentifiedElementKind(id.into()),
|
||||
kind: IdentifiedElement(id.into()),
|
||||
children: self.children,
|
||||
group: self.group,
|
||||
base_style: self.base_style,
|
||||
|
@ -112,115 +112,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<V> Div<V, IdentifiedElementKind>
|
||||
impl<V, K> Interactive for Div<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
pub fn on_mouse_down(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut V, &MouseDownEvent, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
self.listeners
|
||||
.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
|
||||
}
|
||||
|
||||
pub fn on_mouse_up(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut V, &MouseUpEvent, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
self.listeners
|
||||
.mouse_up
|
||||
.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
|
||||
}
|
||||
|
||||
pub fn on_mouse_down_out(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut V, &MouseDownEvent, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
self.listeners
|
||||
.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
|
||||
}
|
||||
|
||||
pub fn on_mouse_up_out(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut V, &MouseUpEvent, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
self.listeners
|
||||
.mouse_up
|
||||
.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
|
||||
}
|
||||
|
||||
pub fn on_mouse_move(
|
||||
mut self,
|
||||
handler: impl Fn(&mut V, &MouseMoveEvent, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
self.listeners
|
||||
.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
|
||||
}
|
||||
|
||||
pub fn on_scroll_wheel(
|
||||
mut self,
|
||||
handler: impl Fn(&mut V, &ScrollWheelEvent, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
self.listeners
|
||||
.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
|
||||
fn listeners(&mut self) -> &mut MouseEventListeners<V> {
|
||||
&mut self.listeners
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Clickable for Div<V, IdentifiedElement> where V: 'static + Send + Sync {}
|
||||
|
||||
impl<V, K> Div<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
pub fn group(mut self, group: impl Into<SharedString>) -> Self {
|
||||
self.group = Some(group.into());
|
||||
|
@ -378,7 +285,7 @@ where
|
|||
up: event.clone(),
|
||||
};
|
||||
for listener in &click_listeners {
|
||||
listener(state, &mouse_click, &bounds, cx);
|
||||
listener(state, &mouse_click, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +328,7 @@ where
|
|||
impl<V, K> Element for Div<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
type ViewState = V;
|
||||
type ElementState = DivState;
|
||||
|
@ -513,16 +420,10 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> IdentifiedElement for Div<V, IdentifiedElementKind> {
|
||||
fn id(&self) -> ElementId {
|
||||
self.kind.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, K> IntoAnyElement<V> for Div<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
|
@ -532,67 +433,13 @@ where
|
|||
impl<V, K> Styled for Div<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn style(&mut self) -> &mut StyleRefinement {
|
||||
&mut self.base_style
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MouseClickEvent {
|
||||
pub down: MouseDownEvent,
|
||||
pub up: MouseUpEvent,
|
||||
}
|
||||
|
||||
type MouseDownHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseDownEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
type MouseUpHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseUpEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
type MouseClickHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseClickEvent, &Bounds<Pixels>, &mut ViewContext<V>) + Send + Sync + 'static,
|
||||
>;
|
||||
|
||||
type MouseMoveHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseMoveEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
type ScrollWheelHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &ScrollWheelEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
|
||||
pub struct MouseEventListeners<V: 'static> {
|
||||
mouse_down: SmallVec<[MouseDownHandler<V>; 2]>,
|
||||
mouse_up: SmallVec<[MouseUpHandler<V>; 2]>,
|
||||
mouse_click: SmallVec<[MouseClickHandler<V>; 2]>,
|
||||
mouse_move: SmallVec<[MouseMoveHandler<V>; 2]>,
|
||||
scroll_wheel: SmallVec<[ScrollWheelHandler<V>; 2]>,
|
||||
}
|
||||
|
||||
impl<V> Default for MouseEventListeners<V> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
mouse_down: SmallVec::new(),
|
||||
mouse_up: SmallVec::new(),
|
||||
mouse_click: SmallVec::new(),
|
||||
mouse_move: SmallVec::new(),
|
||||
scroll_wheel: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_hover_listener<V>(bounds: Bounds<Pixels>, cx: &mut ViewContext<V>)
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
use crate::{
|
||||
div, AnonymousElementKind, AnyElement, BorrowWindow, Bounds, Div, DivState, Element, ElementId,
|
||||
ElementKind, IdentifiedElement, IdentifiedElementKind, IntoAnyElement, LayoutId, Pixels,
|
||||
SharedString, StyleRefinement, Styled, ViewContext,
|
||||
div, AnonymousElement, AnyElement, BorrowWindow, Bounds, Clickable, Div, DivState, Element,
|
||||
ElementId, ElementIdentity, IdentifiedElement, Interactive, IntoAnyElement, LayoutId,
|
||||
MouseEventListeners, Pixels, SharedString, StyleRefinement, Styled, ViewContext,
|
||||
};
|
||||
use futures::FutureExt;
|
||||
use util::ResultExt;
|
||||
|
||||
pub struct Img<V: 'static + Send + Sync, K: ElementKind = AnonymousElementKind> {
|
||||
pub struct Img<V: 'static + Send + Sync, K: ElementIdentity = AnonymousElement> {
|
||||
base: Div<V, K>,
|
||||
uri: Option<SharedString>,
|
||||
grayscale: bool,
|
||||
}
|
||||
|
||||
pub fn img<V>() -> Img<V, AnonymousElementKind>
|
||||
pub fn img<V>() -> Img<V, AnonymousElement>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ where
|
|||
impl<V, K> Img<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
pub fn uri(mut self, uri: impl Into<SharedString>) -> Self {
|
||||
self.uri = Some(uri.into());
|
||||
|
@ -39,8 +39,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> Img<V, AnonymousElementKind> {
|
||||
pub fn id(self, id: impl Into<ElementId>) -> Img<V, IdentifiedElementKind> {
|
||||
impl<V: 'static + Send + Sync> Img<V, AnonymousElement> {
|
||||
pub fn id(self, id: impl Into<ElementId>) -> Img<V, IdentifiedElement> {
|
||||
Img {
|
||||
base: self.base.id(id),
|
||||
uri: self.uri,
|
||||
|
@ -52,7 +52,7 @@ impl<V: 'static + Send + Sync> Img<V, AnonymousElementKind> {
|
|||
impl<V, K> IntoAnyElement<V> for Img<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
|
@ -62,7 +62,7 @@ where
|
|||
impl<V, K> Element for Img<V, K>
|
||||
where
|
||||
V: Send + Sync + 'static,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
type ViewState = V;
|
||||
type ElementState = DivState;
|
||||
|
@ -121,18 +121,24 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> IdentifiedElement for Img<V, IdentifiedElementKind> {
|
||||
fn id(&self) -> ElementId {
|
||||
IdentifiedElement::id(&self.base)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, K> Styled for Img<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn style(&mut self) -> &mut StyleRefinement {
|
||||
self.base.style()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, K> Interactive for Img<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn listeners(&mut self) -> &mut MouseEventListeners<V> {
|
||||
self.base.listeners()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Clickable for Img<V, IdentifiedElement> where V: 'static + Send + Sync {}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use crate::{
|
||||
div, AnonymousElementKind, AnyElement, Bounds, Div, DivState, Element, ElementId, ElementKind,
|
||||
IdentifiedElement, IdentifiedElementKind, IntoAnyElement, LayoutId, Pixels, SharedString,
|
||||
StyleRefinement, Styled,
|
||||
div, AnonymousElement, AnyElement, Bounds, Clickable, Div, DivState, Element, ElementId,
|
||||
ElementIdentity, IdentifiedElement, Interactive, IntoAnyElement, LayoutId, MouseEventListeners,
|
||||
Pixels, SharedString, StyleRefinement, Styled,
|
||||
};
|
||||
use util::ResultExt;
|
||||
|
||||
pub struct Svg<V: 'static + Send + Sync, K: ElementKind = AnonymousElementKind> {
|
||||
pub struct Svg<V: 'static + Send + Sync, K: ElementIdentity = AnonymousElement> {
|
||||
base: Div<V, K>,
|
||||
path: Option<SharedString>,
|
||||
}
|
||||
|
||||
pub fn svg<V>() -> Svg<V, AnonymousElementKind>
|
||||
pub fn svg<V>() -> Svg<V, AnonymousElement>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ where
|
|||
impl<V, K> Svg<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
pub fn path(mut self, path: impl Into<SharedString>) -> Self {
|
||||
self.path = Some(path.into());
|
||||
|
@ -31,8 +31,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> Svg<V, AnonymousElementKind> {
|
||||
pub fn id(self, id: impl Into<ElementId>) -> Svg<V, IdentifiedElementKind> {
|
||||
impl<V: 'static + Send + Sync> Svg<V, AnonymousElement> {
|
||||
pub fn id(self, id: impl Into<ElementId>) -> Svg<V, IdentifiedElement> {
|
||||
Svg {
|
||||
base: self.base.id(id),
|
||||
path: self.path,
|
||||
|
@ -43,7 +43,7 @@ impl<V: 'static + Send + Sync> Svg<V, AnonymousElementKind> {
|
|||
impl<V, K> IntoAnyElement<V> for Svg<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn into_any(self) -> AnyElement<V> {
|
||||
AnyElement::new(self)
|
||||
|
@ -53,7 +53,7 @@ where
|
|||
impl<V, K> Element for Svg<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
type ViewState = V;
|
||||
type ElementState = DivState;
|
||||
|
@ -96,18 +96,24 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: 'static + Send + Sync> IdentifiedElement for Svg<V, IdentifiedElementKind> {
|
||||
fn id(&self) -> ElementId {
|
||||
IdentifiedElement::id(&self.base)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, K> Styled for Svg<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementKind,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn style(&mut self) -> &mut StyleRefinement {
|
||||
self.base.style()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V, K> Interactive for Svg<V, K>
|
||||
where
|
||||
V: 'static + Send + Sync,
|
||||
K: ElementIdentity,
|
||||
{
|
||||
fn listeners(&mut self) -> &mut MouseEventListeners<V> {
|
||||
self.base.listeners()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Clickable for Svg<V, IdentifiedElement> where V: 'static + Send + Sync {}
|
||||
|
|
|
@ -7,6 +7,7 @@ mod events;
|
|||
mod executor;
|
||||
mod geometry;
|
||||
mod image_cache;
|
||||
mod interactive;
|
||||
mod platform;
|
||||
mod scene;
|
||||
mod style;
|
||||
|
@ -30,6 +31,7 @@ pub use executor::*;
|
|||
pub use geometry::*;
|
||||
pub use gpui3_macros::*;
|
||||
pub use image_cache::*;
|
||||
pub use interactive::*;
|
||||
pub use platform::*;
|
||||
pub use refineable::*;
|
||||
pub use scene::*;
|
||||
|
|
218
crates/gpui3/src/interactive.rs
Normal file
218
crates/gpui3/src/interactive.rs
Normal file
|
@ -0,0 +1,218 @@
|
|||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{
|
||||
Bounds, DispatchPhase, Element, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
|
||||
Pixels, ScrollWheelEvent, ViewContext,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait Interactive: Element {
|
||||
fn listeners(&mut self) -> &mut MouseEventListeners<Self::ViewState>;
|
||||
|
||||
fn on_mouse_down(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut Self::ViewState, &MouseDownEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.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
|
||||
}
|
||||
|
||||
fn on_mouse_up(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut Self::ViewState, &MouseUpEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.mouse_up
|
||||
.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
|
||||
}
|
||||
|
||||
fn on_mouse_down_out(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut Self::ViewState, &MouseDownEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.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
|
||||
}
|
||||
|
||||
fn on_mouse_up_out(
|
||||
mut self,
|
||||
button: MouseButton,
|
||||
handler: impl Fn(&mut Self::ViewState, &MouseUpEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.mouse_up
|
||||
.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
|
||||
}
|
||||
|
||||
fn on_mouse_move(
|
||||
mut self,
|
||||
handler: impl Fn(&mut Self::ViewState, &MouseMoveEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.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
|
||||
}
|
||||
|
||||
fn on_scroll_wheel(
|
||||
mut self,
|
||||
handler: impl Fn(&mut Self::ViewState, &ScrollWheelEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.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
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Clickable: Interactive {
|
||||
fn on_click(
|
||||
mut self,
|
||||
handler: impl Fn(&mut Self::ViewState, &MouseClickEvent, &mut ViewContext<Self::ViewState>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.listeners()
|
||||
.mouse_click
|
||||
.push(Arc::new(move |view, event, cx| handler(view, event, cx)));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
type MouseDownHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseDownEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
type MouseUpHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseUpEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
type MouseClickHandler<V> =
|
||||
Arc<dyn Fn(&mut V, &MouseClickEvent, &mut ViewContext<V>) + Send + Sync + 'static>;
|
||||
|
||||
type MouseMoveHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &MouseMoveEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
type ScrollWheelHandler<V> = Arc<
|
||||
dyn Fn(&mut V, &ScrollWheelEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>;
|
||||
|
||||
pub struct MouseEventListeners<V: 'static> {
|
||||
pub mouse_down: SmallVec<[MouseDownHandler<V>; 2]>,
|
||||
pub mouse_up: SmallVec<[MouseUpHandler<V>; 2]>,
|
||||
pub mouse_click: SmallVec<[MouseClickHandler<V>; 2]>,
|
||||
pub mouse_move: SmallVec<[MouseMoveHandler<V>; 2]>,
|
||||
pub scroll_wheel: SmallVec<[ScrollWheelHandler<V>; 2]>,
|
||||
}
|
||||
|
||||
impl<V> Default for MouseEventListeners<V> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
mouse_down: SmallVec::new(),
|
||||
mouse_up: SmallVec::new(),
|
||||
mouse_click: SmallVec::new(),
|
||||
mouse_move: SmallVec::new(),
|
||||
scroll_wheel: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MouseClickEvent {
|
||||
pub down: MouseDownEvent,
|
||||
pub up: MouseUpEvent,
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use parking_lot::Mutex;
|
||||
|
||||
use crate::{
|
||||
AnyBox, AnyElement, BorrowWindow, Bounds, Element, ElementId, EntityId, Handle,
|
||||
IdentifiedElement, IntoAnyElement, LayoutId, Pixels, ViewContext, WindowContext,
|
||||
AnyBox, AnyElement, BorrowWindow, Bounds, Element, ElementId, EntityId, Handle, IntoAnyElement,
|
||||
LayoutId, Pixels, ViewContext, WindowContext,
|
||||
};
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
|
@ -86,8 +86,6 @@ impl<S: 'static + Send + Sync> Element for View<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: Send + Sync + 'static> IdentifiedElement for View<S> {}
|
||||
|
||||
struct EraseViewState<ViewState: 'static + Send + Sync, ParentViewState> {
|
||||
view: View<ViewState>,
|
||||
parent_view_state_type: PhantomData<ParentViewState>,
|
||||
|
@ -148,7 +146,7 @@ impl<S: Send + Sync + 'static> ViewObject for View<S> {
|
|||
}
|
||||
|
||||
fn layout(&mut self, cx: &mut WindowContext) -> (LayoutId, AnyBox) {
|
||||
cx.with_element_id(IdentifiedElement::id(self), |cx| {
|
||||
cx.with_element_id(self.entity_id(), |cx| {
|
||||
self.state.update(cx, |state, cx| {
|
||||
let mut element = (self.render)(state, cx);
|
||||
let layout_id = element.layout(state, cx);
|
||||
|
@ -159,7 +157,7 @@ impl<S: Send + Sync + 'static> ViewObject for View<S> {
|
|||
}
|
||||
|
||||
fn paint(&mut self, _: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext) {
|
||||
cx.with_element_id(IdentifiedElement::id(self), |cx| {
|
||||
cx.with_element_id(self.entity_id(), |cx| {
|
||||
self.state.update(cx, |state, cx| {
|
||||
let element = element.downcast_mut::<AnyElement<S>>().unwrap();
|
||||
element.paint(state, None, cx);
|
||||
|
|
|
@ -1145,6 +1145,13 @@ impl From<SmallVec<[u32; 16]>> for StackingOrder {
|
|||
pub enum ElementId {
|
||||
View(EntityId),
|
||||
Number(usize),
|
||||
Name(SharedString),
|
||||
}
|
||||
|
||||
impl From<EntityId> for ElementId {
|
||||
fn from(id: EntityId) -> Self {
|
||||
ElementId::View(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for ElementId {
|
||||
|
@ -1158,3 +1165,9 @@ impl From<i32> for ElementId {
|
|||
Self::Number(id as usize)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SharedString> for ElementId {
|
||||
fn from(id: SharedString) -> Self {
|
||||
ElementId::Name(id)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue