Skip to content

Commit

Permalink
Action type erasure
Browse files Browse the repository at this point in the history
  • Loading branch information
wtholliday committed Dec 10, 2023
1 parent 03476fa commit caeb27e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 28 deletions.
12 changes: 6 additions & 6 deletions src/modifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,22 +114,22 @@ pub trait Modifiers: View + Sized {
}

/// Calls a function in response to a tap.
fn tap<A: 'static, F: Fn(&mut Context) -> A + 'static>(self, f: F) -> Tap<Self, TapAdapter::<F>, A> {
Tap::new(self, TapAdapter::<F>{f})
fn tap<A: 'static, F: Fn(&mut Context) -> A + 'static>(self, f: F) -> Tap<Self, TapAdapter<F>> {
Tap::new(self, TapAdapter{f})
}

/// Version of `tap` which takes an action type instead
/// of a function.
fn tap_a<A: Clone + 'static>(self, action: A) -> Tap<Self, TapActionAdapter::<A>, A> {
Tap::new(self, TapActionAdapter::<A>{action})
fn tap_a<A: Clone + 'static>(self, action: A) -> Tap<Self, TapActionAdapter<A>> {
Tap::new(self, TapActionAdapter{action})
}

/// Version of `tap` which passes the tap position and mouse button.
fn tap_p<A: 'static, F: Fn(&mut Context, LocalPoint, Option<MouseButton>) -> A + 'static>(
self,
f: F,
) -> Tap<Self, TapFunc::<F>, A> {
Tap::new(self, TapFunc::<F>{f})
) -> Tap<Self, TapFunc<F>> {
Tap::new(self, TapFunc{f})
}

/// Specify the title of the window.
Expand Down
41 changes: 19 additions & 22 deletions src/views/tap.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,63 @@
use crate::*;
use std::any::Any;

pub trait TapFn<A> {
fn call(&self, cx: &mut Context, pt: LocalPoint, button: Option<MouseButton>) -> A;
pub trait TapFn {
fn call(&self, cx: &mut Context, pt: LocalPoint, button: Option<MouseButton>, actions: &mut Vec<Box<dyn Any>>);
}

pub struct TapFunc<F> {
pub f: F
}

impl<A: 'static, F: Fn(&mut Context, LocalPoint, Option<MouseButton>) -> A> TapFn<A> for TapFunc<F> {
fn call(&self, cx: &mut Context, pt: LocalPoint, button: Option<MouseButton>) -> A {
(self.f)(cx, pt, button)
impl<A: 'static, F: Fn(&mut Context, LocalPoint, Option<MouseButton>) -> A> TapFn for TapFunc<F> {
fn call(&self, cx: &mut Context, pt: LocalPoint, button: Option<MouseButton>, actions: &mut Vec<Box<dyn Any>>) {
actions.push(Box::new((self.f)(cx, pt, button)))
}
}

pub struct TapAdapter<F> {
pub f: F
}

impl<A: 'static, F: Fn(&mut Context) -> A> TapFn<A> for TapAdapter<F> {
fn call(&self, cx: &mut Context, _pt: LocalPoint, _button: Option<MouseButton>) -> A {
(self.f)(cx)
impl<A: 'static, F: Fn(&mut Context) -> A> TapFn for TapAdapter<F> {
fn call(&self, cx: &mut Context, _pt: LocalPoint, _button: Option<MouseButton>, actions: &mut Vec<Box<dyn Any>>) {
actions.push(Box::new((self.f)(cx)))
}
}

pub struct TapActionAdapter<A> {
pub action: A
}

impl<A: Clone + 'static> TapFn<A> for TapActionAdapter<A> {
fn call(&self, _cx: &mut Context, _pt: LocalPoint, _button: Option<MouseButton>) -> A {
self.action.clone()
impl<A: Clone + 'static> TapFn for TapActionAdapter<A> {
fn call(&self, _cx: &mut Context, _pt: LocalPoint, _button: Option<MouseButton>, actions: &mut Vec<Box<dyn Any>>) {
actions.push(Box::new(self.action.clone()))
}
}

/// Struct for the `tap` gesture.
pub struct Tap<V: View, F, A> {
pub struct Tap<V: View, F> {
/// Child view tree.
child: V,

/// Called when a tap occurs.
func: F,

phantom_a: std::marker::PhantomData<A>
}

impl<V, F, A> Tap<V, F, A>
impl<V, F> Tap<V, F>
where
V: View,
F: TapFn<A> + 'static,
F: TapFn + 'static,
{
pub fn new(v: V, f: F) -> Self {
Self { child: v, func: f, phantom_a: std::marker::PhantomData::default() }
Self { child: v, func: f }
}
}

impl<V, F, A> View for Tap<V, F, A>
impl<V, F> View for Tap<V, F>
where
V: View,
F: TapFn<A> + 'static,
A: 'static,
F: TapFn + 'static,
{
fn process(
&self,
Expand All @@ -79,7 +76,7 @@ where
Event::TouchEnd { id, position } => {
if cx.touches[*id] == vid {
cx.touches[*id] = ViewId::default();
actions.push(Box::new(self.func.call(cx, *position, cx.mouse_button)))
self.func.call(cx, *position, cx.mouse_button, actions)
}
}
_ => (),
Expand Down Expand Up @@ -131,4 +128,4 @@ where
}
}

impl<V, F, A> private::Sealed for Tap<V, F, A> where V: View {}
impl<V, F> private::Sealed for Tap<V, F> where V: View {}

0 comments on commit caeb27e

Please sign in to comment.