WIP
This commit is contained in:
parent
d0dd44faad
commit
25ed7c57c1
4 changed files with 87 additions and 106 deletions
|
@ -1,10 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext,
|
point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext,
|
||||||
BorrowWindow, Bounds, CallbackHandle, ClickEvent, ConstructorHandle, DispatchPhase, Element,
|
BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusEvent, FocusHandle,
|
||||||
ElementId, FocusEvent, FocusHandle, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId,
|
KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, MouseMoveEvent,
|
||||||
MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point,
|
MouseUpEvent, ParentElement, Pixels, Point, Render, RenderOnce, ScrollWheelEvent, SharedString,
|
||||||
Render, RenderOnce, ScrollWheelEvent, SharedString, Size, Style, StyleRefinement, Styled, Task,
|
Size, Style, StyleRefinement, Styled, Task, View, Visibility, WindowContext,
|
||||||
View, Visibility, WindowContext,
|
|
||||||
};
|
};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use refineable::Refineable;
|
use refineable::Refineable;
|
||||||
|
@ -79,28 +78,29 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
fn on_mouse_down(
|
fn on_mouse_down(
|
||||||
mut self,
|
mut self,
|
||||||
button: MouseButton,
|
button: MouseButton,
|
||||||
handler: impl Into<CallbackHandle<MouseDownEvent>>,
|
listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let handler = handler.into();
|
|
||||||
self.interactivity().mouse_down_listeners.push(Box::new(
|
self.interactivity().mouse_down_listeners.push(Box::new(
|
||||||
move |event, bounds, phase, cx| {
|
move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Bubble
|
if phase == DispatchPhase::Bubble
|
||||||
&& event.button == button
|
&& event.button == button
|
||||||
&& bounds.contains_point(&event.position)
|
&& bounds.contains_point(&event.position)
|
||||||
{
|
{
|
||||||
(handler.callback)(event, cx)
|
(listener)(event, cx)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_any_mouse_down(mut self, handler: impl Into<CallbackHandle<MouseDownEvent>>) -> Self {
|
fn on_any_mouse_down(
|
||||||
let handler = handler.into();
|
mut self,
|
||||||
|
listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity().mouse_down_listeners.push(Box::new(
|
self.interactivity().mouse_down_listeners.push(Box::new(
|
||||||
move |event, bounds, phase, cx| {
|
move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
||||||
(handler.callback)(event, cx)
|
(listener)(event, cx)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
@ -110,9 +110,8 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
fn on_mouse_up(
|
fn on_mouse_up(
|
||||||
mut self,
|
mut self,
|
||||||
button: MouseButton,
|
button: MouseButton,
|
||||||
handler: impl Into<CallbackHandle<MouseUpEvent>>,
|
listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let handler = handler.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.mouse_up_listeners
|
.mouse_up_listeners
|
||||||
.push(Box::new(move |event, bounds, phase, cx| {
|
.push(Box::new(move |event, bounds, phase, cx| {
|
||||||
|
@ -120,30 +119,34 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
&& event.button == button
|
&& event.button == button
|
||||||
&& bounds.contains_point(&event.position)
|
&& bounds.contains_point(&event.position)
|
||||||
{
|
{
|
||||||
(handler.callback)(event, cx)
|
(listener)(event, cx)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_any_mouse_up(mut self, handler: impl Into<CallbackHandle<MouseUpEvent>>) -> Self {
|
fn on_any_mouse_up(
|
||||||
let handler = handler.into();
|
mut self,
|
||||||
|
listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.mouse_up_listeners
|
.mouse_up_listeners
|
||||||
.push(Box::new(move |event, bounds, phase, cx| {
|
.push(Box::new(move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
||||||
(handler.callback)(event, cx)
|
(listener)(event, cx)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_mouse_down_out(mut self, handler: impl Into<CallbackHandle<MouseDownEvent>>) -> Self {
|
fn on_mouse_down_out(
|
||||||
let handler = handler.into();
|
mut self,
|
||||||
|
listener: impl Fn(&MouseDownEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity().mouse_down_listeners.push(Box::new(
|
self.interactivity().mouse_down_listeners.push(Box::new(
|
||||||
move |event, bounds, phase, cx| {
|
move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Capture && !bounds.contains_point(&event.position) {
|
if phase == DispatchPhase::Capture && !bounds.contains_point(&event.position) {
|
||||||
(handler.callback)(event, cx)
|
(listener)(event, cx)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
@ -153,9 +156,8 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
fn on_mouse_up_out(
|
fn on_mouse_up_out(
|
||||||
mut self,
|
mut self,
|
||||||
button: MouseButton,
|
button: MouseButton,
|
||||||
handler: impl Into<CallbackHandle<MouseUpEvent>>,
|
listener: impl Fn(&MouseUpEvent, &mut WindowContext) + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let handler = handler.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.mouse_up_listeners
|
.mouse_up_listeners
|
||||||
.push(Box::new(move |event, bounds, phase, cx| {
|
.push(Box::new(move |event, bounds, phase, cx| {
|
||||||
|
@ -163,30 +165,34 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
&& event.button == button
|
&& event.button == button
|
||||||
&& !bounds.contains_point(&event.position)
|
&& !bounds.contains_point(&event.position)
|
||||||
{
|
{
|
||||||
(handler.callback)(event, cx);
|
(listener)(event, cx);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_mouse_move(mut self, handler: impl Into<CallbackHandle<MouseMoveEvent>>) -> Self {
|
fn on_mouse_move(
|
||||||
let handler = handler.into();
|
mut self,
|
||||||
|
listener: impl Fn(&MouseMoveEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity().mouse_move_listeners.push(Box::new(
|
self.interactivity().mouse_move_listeners.push(Box::new(
|
||||||
move |event, bounds, phase, cx| {
|
move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
||||||
(handler.callback)(event, cx);
|
(listener)(event, cx);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_scroll_wheel(mut self, handler: impl Into<CallbackHandle<ScrollWheelEvent>>) -> Self {
|
fn on_scroll_wheel(
|
||||||
let handler = handler.into();
|
mut self,
|
||||||
|
listener: impl Fn(&ScrollWheelEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity().scroll_wheel_listeners.push(Box::new(
|
self.interactivity().scroll_wheel_listeners.push(Box::new(
|
||||||
move |event, bounds, phase, cx| {
|
move |event, bounds, phase, cx| {
|
||||||
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
|
||||||
(handler.callback)(event, cx);
|
(listener)(event, cx);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
@ -194,14 +200,16 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Capture the given action, before normal action dispatch can fire
|
/// Capture the given action, before normal action dispatch can fire
|
||||||
fn capture_action<A: Action>(mut self, listener: impl Into<CallbackHandle<A>>) -> Self {
|
fn capture_action<A: Action>(
|
||||||
let listener = listener.into();
|
mut self,
|
||||||
|
listener: impl Fn(&A, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity().action_listeners.push((
|
self.interactivity().action_listeners.push((
|
||||||
TypeId::of::<A>(),
|
TypeId::of::<A>(),
|
||||||
Box::new(move |action, phase, cx| {
|
Box::new(move |action, phase, cx| {
|
||||||
let action = action.downcast_ref().unwrap();
|
let action = action.downcast_ref().unwrap();
|
||||||
if phase == DispatchPhase::Capture {
|
if phase == DispatchPhase::Capture {
|
||||||
(listener.callback)(action, cx)
|
(listener)(action, cx)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
@ -209,8 +217,7 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a listener for the given action, fires during the bubble event phase
|
/// Add a listener for the given action, fires during the bubble event phase
|
||||||
fn on_action<A: Action>(mut self, listener: impl Into<CallbackHandle<A>> + 'static) -> Self {
|
fn on_action<A: Action>(mut self, listener: impl Fn(&A, &mut WindowContext) + 'static) -> Self {
|
||||||
let handle = listener.into();
|
|
||||||
// NOTE: this debug assert has the side-effect of working around
|
// NOTE: this debug assert has the side-effect of working around
|
||||||
// a bug where a crate consisting only of action definitions does
|
// a bug where a crate consisting only of action definitions does
|
||||||
// not register the actions in debug builds:
|
// not register the actions in debug builds:
|
||||||
|
@ -230,27 +237,31 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
Box::new(move |action, phase, cx| {
|
Box::new(move |action, phase, cx| {
|
||||||
let action = action.downcast_ref().unwrap();
|
let action = action.downcast_ref().unwrap();
|
||||||
if phase == DispatchPhase::Bubble {
|
if phase == DispatchPhase::Bubble {
|
||||||
(handle.callback)(action, cx)
|
(listener)(action, cx)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_key_down(mut self, listener: impl Into<CallbackHandle<KeyDownEvent>>) -> Self {
|
fn on_key_down(
|
||||||
let listener = listener.into();
|
mut self,
|
||||||
|
listener: impl Fn(&KeyDownEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.key_down_listeners
|
.key_down_listeners
|
||||||
.push(Box::new(move |event, phase, cx| {
|
.push(Box::new(move |event, phase, cx| {
|
||||||
if phase == DispatchPhase::Bubble {
|
if phase == DispatchPhase::Bubble {
|
||||||
(listener.callback)(event, cx)
|
(listener)(event, cx)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capture_key_down(mut self, listener: impl Into<CallbackHandle<KeyDownEvent>>) -> Self {
|
fn capture_key_down(
|
||||||
let listener = listener.into();
|
mut self,
|
||||||
|
listener: impl Fn(&KeyDownEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.key_down_listeners
|
.key_down_listeners
|
||||||
.push(Box::new(move |event, phase, cx| {
|
.push(Box::new(move |event, phase, cx| {
|
||||||
|
@ -261,8 +272,7 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_key_up(mut self, listener: impl Into<CallbackHandle<KeyUpEvent>>) -> Self {
|
fn on_key_up(mut self, listener: impl Fn(&KeyUpEvent, &mut WindowContext) + 'static) -> Self {
|
||||||
let listener = listener.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.key_up_listeners
|
.key_up_listeners
|
||||||
.push(Box::new(move |event, phase, cx| {
|
.push(Box::new(move |event, phase, cx| {
|
||||||
|
@ -273,8 +283,10 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn capture_key_up(mut self, listener: impl Into<CallbackHandle<KeyUpEvent>>) -> Self {
|
fn capture_key_up(
|
||||||
let listener = listener.into();
|
mut self,
|
||||||
|
listener: impl Fn(&KeyUpEvent, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.key_up_listeners
|
.key_up_listeners
|
||||||
.push(Box::new(move |event, phase, cx| {
|
.push(Box::new(move |event, phase, cx| {
|
||||||
|
@ -307,8 +319,10 @@ pub trait InteractiveElement: Sized + Element {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_drop<W: 'static>(mut self, listener: impl Into<CallbackHandle<View<W>>>) -> Self {
|
fn on_drop<W: 'static>(
|
||||||
let listener = listener.into();
|
mut self,
|
||||||
|
listener: impl Fn(&View<W>, &mut WindowContext) + 'static,
|
||||||
|
) -> Self {
|
||||||
self.interactivity().drop_listeners.push((
|
self.interactivity().drop_listeners.push((
|
||||||
TypeId::of::<W>(),
|
TypeId::of::<W>(),
|
||||||
Box::new(move |dragged_view, cx| {
|
Box::new(move |dragged_view, cx| {
|
||||||
|
@ -364,23 +378,21 @@ pub trait StatefulInteractiveElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_click(mut self, listener: impl Into<CallbackHandle<ClickEvent>>) -> Self
|
fn on_click(mut self, listener: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.click_listeners
|
.click_listeners
|
||||||
.push(Box::new(move |event, cx| (listener.callback)(event, cx)));
|
.push(Box::new(move |event, cx| (listener.callback)(event, cx)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_drag<W>(mut self, listener: impl Into<ConstructorHandle<View<W>>>) -> Self
|
fn on_drag<W>(mut self, listener: impl Fn(&mut WindowContext) -> View<W> + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
W: 'static + Render,
|
W: 'static + Render,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.interactivity().drag_listener.is_none(),
|
self.interactivity().drag_listener.is_none(),
|
||||||
"calling on_drag more than once on the same element is not supported"
|
"calling on_drag more than once on the same element is not supported"
|
||||||
|
@ -392,24 +404,22 @@ pub trait StatefulInteractiveElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_hover(mut self, listener: impl Into<CallbackHandle<bool>>) -> Self
|
fn on_hover(mut self, listener: impl Fn(&bool, &mut WindowContext) + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.interactivity().hover_listener.is_none(),
|
self.interactivity().hover_listener.is_none(),
|
||||||
"calling on_hover more than once on the same element is not supported"
|
"calling on_hover more than once on the same element is not supported"
|
||||||
);
|
);
|
||||||
self.interactivity().hover_listener = Some(listener);
|
self.interactivity().hover_listener = Some(Box::new(listener));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tooltip(mut self, build_tooltip: impl Into<ConstructorHandle<AnyView>>) -> Self
|
fn tooltip(mut self, build_tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let build_tooltip = build_tooltip.into();
|
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.interactivity().tooltip_builder.is_none(),
|
self.interactivity().tooltip_builder.is_none(),
|
||||||
"calling tooltip more than once on the same element is not supported"
|
"calling tooltip more than once on the same element is not supported"
|
||||||
|
@ -438,11 +448,10 @@ pub trait FocusableElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus(mut self, listener: impl Into<CallbackHandle<FocusEvent>>) -> Self
|
fn on_focus(mut self, listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.focus_listeners
|
.focus_listeners
|
||||||
.push(Box::new(move |focus_handle, event, cx| {
|
.push(Box::new(move |focus_handle, event, cx| {
|
||||||
|
@ -453,11 +462,10 @@ pub trait FocusableElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_blur(mut self, listener: impl Into<CallbackHandle<FocusEvent>>) -> Self
|
fn on_blur(mut self, listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.focus_listeners
|
.focus_listeners
|
||||||
.push(Box::new(move |focus_handle, event, cx| {
|
.push(Box::new(move |focus_handle, event, cx| {
|
||||||
|
@ -468,11 +476,10 @@ pub trait FocusableElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_in(mut self, listener: impl Into<CallbackHandle<FocusEvent>>) -> Self
|
fn on_focus_in(mut self, listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.focus_listeners
|
.focus_listeners
|
||||||
.push(Box::new(move |focus_handle, event, cx| {
|
.push(Box::new(move |focus_handle, event, cx| {
|
||||||
|
@ -492,11 +499,10 @@ pub trait FocusableElement: InteractiveElement {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus_out(mut self, listener: impl Into<CallbackHandle<FocusEvent>>) -> Self
|
fn on_focus_out(mut self, listener: impl Fn(&FocusEvent, &mut WindowContext) + 'static) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let listener = listener.into();
|
|
||||||
self.interactivity()
|
self.interactivity()
|
||||||
.focus_listeners
|
.focus_listeners
|
||||||
.push(Box::new(move |focus_handle, event, cx| {
|
.push(Box::new(move |focus_handle, event, cx| {
|
||||||
|
@ -710,7 +716,7 @@ pub struct Interactivity {
|
||||||
pub drop_listeners: SmallVec<[(TypeId, Box<DropListener>); 2]>,
|
pub drop_listeners: SmallVec<[(TypeId, Box<DropListener>); 2]>,
|
||||||
pub click_listeners: SmallVec<[ClickListener; 2]>,
|
pub click_listeners: SmallVec<[ClickListener; 2]>,
|
||||||
pub drag_listener: Option<DragListener>,
|
pub drag_listener: Option<DragListener>,
|
||||||
pub hover_listener: Option<CallbackHandle<bool>>,
|
pub hover_listener: Option<Box<dyn Fn(&bool, &mut WindowContext)>>,
|
||||||
pub tooltip_builder: Option<TooltipBuilder>,
|
pub tooltip_builder: Option<TooltipBuilder>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,30 +194,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CallbackHandle<E> {
|
|
||||||
callback: Box<dyn Fn(&E, &mut WindowContext) + 'static>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E, F: Fn(&E, &mut WindowContext) + 'static> From<F> for CallbackHandle<E> {
|
|
||||||
fn from(value: F) -> Self {
|
|
||||||
CallbackHandle {
|
|
||||||
callback: Box::new(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ConstructorHandle<R> {
|
|
||||||
callback: Box<dyn Fn(&mut WindowContext) -> R + 'static>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R, F: Fn(&mut WindowContext) -> R + 'static> From<F> for ConstructorHandle<R> {
|
|
||||||
fn from(value: F) -> Self {
|
|
||||||
ConstructorHandle {
|
|
||||||
callback: Box::new(value),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Flatten<T> {
|
pub trait Flatten<T> {
|
||||||
fn flatten(self) -> Result<T>;
|
fn flatten(self) -> Result<T>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,7 +305,7 @@ mod test {
|
||||||
div().id("testview").child(
|
div().id("testview").child(
|
||||||
div()
|
div()
|
||||||
.key_context("parent")
|
.key_context("parent")
|
||||||
.on_key_down(cx.callback(|this, _, _| this.saw_key_down = true))
|
.on_key_down(cx.listener(|this, _, _| this.saw_key_down = true))
|
||||||
.on_action(
|
.on_action(
|
||||||
cx.callback(|this: &mut TestView, _: &TestAction, _| {
|
cx.callback(|this: &mut TestView, _: &TestAction, _| {
|
||||||
this.saw_action = true
|
this.saw_action = true
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext,
|
key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext,
|
||||||
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, CallbackHandle, ConstructorHandle,
|
AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
|
||||||
Context, Corners, CursorStyle, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges,
|
DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
|
||||||
Effect, Entity, EntityId, EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId,
|
EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
|
||||||
GlobalElementId, GlyphId, Hsla, ImageData, InputEvent, IsZero, KeyBinding, KeyContext,
|
ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model,
|
||||||
KeyDownEvent, LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton,
|
ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
|
||||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay,
|
MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
|
||||||
PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render,
|
PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
|
||||||
RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow,
|
RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
|
||||||
SharedString, Size, Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, Underline,
|
Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View,
|
||||||
UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
@ -2283,23 +2283,22 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||||
self.defer(|_, cx| cx.emit(Manager::Dismiss))
|
self.defer(|_, cx| cx.emit(Manager::Dismiss))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn callback<E>(
|
pub fn listener<E>(
|
||||||
&self,
|
&self,
|
||||||
f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
|
f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
|
||||||
) -> CallbackHandle<E> {
|
) -> impl Fn(&E, &mut WindowContext) + 'static {
|
||||||
let view = self.view().clone();
|
let view = self.view().clone();
|
||||||
(move |e: &E, cx: &mut WindowContext| {
|
move |e: &E, cx: &mut WindowContext| {
|
||||||
view.update(cx, |view, cx| f(view, e, cx));
|
view.update(cx, |view, cx| f(view, e, cx));
|
||||||
})
|
}
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constructor<R>(
|
pub fn constructor<R>(
|
||||||
&self,
|
&self,
|
||||||
f: impl Fn(&mut V, &mut ViewContext<V>) -> R + 'static,
|
f: impl Fn(&mut V, &mut ViewContext<V>) -> R + 'static,
|
||||||
) -> ConstructorHandle<R> {
|
) -> impl Fn(&mut WindowContext) -> R {
|
||||||
let view = self.view().clone();
|
let view = self.view().clone();
|
||||||
(move |cx: &mut WindowContext| view.update(cx, |view, cx| f(view, cx))).into()
|
move |cx: &mut WindowContext| view.update(cx, |view, cx| f(view, cx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue