From 49d60af65146845f16fd74e19a9b370cd3db4080 Mon Sep 17 00:00:00 2001 From: Taylor Holliday Date: Sun, 10 Dec 2023 00:43:26 -0800 Subject: [PATCH] Reduce duplicate code for tap gesture (#58) * Try use TapP for both tap and tap_p * Fix compilation * Remove unused code * Move code * Rename * Eliminate TapA * Fix warning --- src/modifiers.rs | 12 ++--- src/views/mod.rs | 2 - src/views/tap.rs | 130 +++++++++++++-------------------------------- src/views/tap_p.rs | 98 ---------------------------------- 4 files changed, 42 insertions(+), 200 deletions(-) delete mode 100644 src/views/tap_p.rs diff --git a/src/modifiers.rs b/src/modifiers.rs index 46b2cba..b175e7f 100644 --- a/src/modifiers.rs +++ b/src/modifiers.rs @@ -114,22 +114,22 @@ pub trait Modifiers: View + Sized { } /// Calls a function in response to a tap. - fn tap A + 'static>(self, f: F) -> Tap { - Tap::new(self, f) + fn tap A + 'static>(self, f: F) -> Tap, A> { + Tap::new(self, TapAdapter::{f}) } /// Version of `tap` which takes an action type instead /// of a function. - fn tap_a(self, action: A) -> TapA { - TapA::new(self, action) + fn tap_a(self, action: A) -> Tap, A> { + Tap::new(self, TapActionAdapter::{action}) } /// Version of `tap` which passes the tap position and mouse button. fn tap_p) -> A + 'static>( self, f: F, - ) -> TapP { - TapP::new(self, f) + ) -> Tap, A> { + Tap::new(self, TapFunc::{f}) } /// Specify the title of the window. diff --git a/src/views/mod.rs b/src/views/mod.rs index 2667693..04968fd 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -67,8 +67,6 @@ mod state; pub use state::*; mod tap; pub use tap::*; -mod tap_p; -pub use tap_p::*; mod text_editor; pub use text_editor::*; mod text; diff --git a/src/views/tap.rs b/src/views/tap.rs index e55f893..f4cce7e 100644 --- a/src/views/tap.rs +++ b/src/views/tap.rs @@ -1,124 +1,66 @@ use crate::*; use std::any::Any; -/// Struct for the `tap` gesture. -pub struct Tap { - /// Child view tree. - child: V, - - /// Called when a tap occurs. - func: F, +pub trait TapFn { + fn call(&self, cx: &mut Context, pt: LocalPoint, button: Option) -> A; } -impl Tap -where - V: View, - F: Fn(&mut Context) -> A + 'static, -{ - pub fn new(v: V, f: F) -> Self { - Self { child: v, func: f } - } +pub struct TapFunc { + pub f: F } -impl View for Tap -where - V: View, - F: Fn(&mut Context) -> A + 'static, - A: 'static, -{ - fn process( - &self, - event: &Event, - path: &mut IdPath, - cx: &mut Context, - actions: &mut Vec>, - ) { - let vid = cx.view_id(path); - match &event { - Event::TouchBegin { id, position } => { - if self.hittest(path, *position, cx).is_some() { - cx.touches[*id] = vid; - } - } - Event::TouchEnd { id, position: _ } => { - if cx.touches[*id] == vid { - cx.touches[*id] = ViewId::default(); - actions.push(Box::new((self.func)(cx))) - } - } - _ => (), - } - } - - fn draw(&self, path: &mut IdPath, args: &mut DrawArgs) { - path.push(0); - self.child.draw(path, args); - path.pop(); - } - - fn layout(&self, path: &mut IdPath, args: &mut LayoutArgs) -> LocalSize { - path.push(0); - let sz = self.child.layout(path, args); - path.pop(); - sz +impl) -> A> TapFn for TapFunc { + fn call(&self, cx: &mut Context, pt: LocalPoint, button: Option) -> A { + (self.f)(cx, pt, button) } +} - fn hittest(&self, path: &mut IdPath, pt: LocalPoint, cx: &mut Context) -> Option { - path.push(0); - let id = self.child.hittest(path, pt, cx); - path.pop(); - id - } +pub struct TapAdapter { + pub f: F +} - fn commands(&self, path: &mut IdPath, cx: &mut Context, cmds: &mut Vec) { - path.push(0); - self.child.commands(path, cx, cmds); - path.pop(); +impl A> TapFn for TapAdapter { + fn call(&self, cx: &mut Context, _pt: LocalPoint, _button: Option) -> A { + (self.f)(cx) } +} - fn gc(&self, path: &mut IdPath, cx: &mut Context, map: &mut Vec) { - path.push(0); - self.child.gc(path, cx, map); - path.pop(); - } +pub struct TapActionAdapter { + pub action: A +} - fn access( - &self, - path: &mut IdPath, - cx: &mut Context, - nodes: &mut Vec<(accesskit::NodeId, accesskit::Node)>, - ) -> Option { - path.push(0); - let node_id = self.child.access(path, cx, nodes); - path.pop(); - node_id +impl TapFn for TapActionAdapter { + fn call(&self, _cx: &mut Context, _pt: LocalPoint, _button: Option) -> A { + self.action.clone() } } -impl private::Sealed for Tap where V: View {} - -/// Struct for the `tap_a` gesture. -pub struct TapA { +/// Struct for the `tap` gesture. +pub struct Tap { /// Child view tree. child: V, /// Called when a tap occurs. - action: A, + func: F, + + phantom_a: std::marker::PhantomData } -impl TapA +impl Tap where V: View, + F: TapFn + 'static, { - pub fn new(child: V, action: A) -> Self { - Self { child, action } + pub fn new(v: V, f: F) -> Self { + Self { child: v, func: f, phantom_a: std::marker::PhantomData::default() } } } -impl View for TapA +impl View for Tap where V: View, - A: Clone + 'static, + F: TapFn + 'static, + A: 'static, { fn process( &self, @@ -134,10 +76,10 @@ where cx.touches[*id] = vid; } } - Event::TouchEnd { id, position: _ } => { + Event::TouchEnd { id, position } => { if cx.touches[*id] == vid { cx.touches[*id] = ViewId::default(); - actions.push(Box::new(self.action.clone())) + actions.push(Box::new(self.func.call(cx, *position, cx.mouse_button))) } } _ => (), @@ -189,4 +131,4 @@ where } } -impl private::Sealed for TapA where V: View {} +impl private::Sealed for Tap where V: View {} diff --git a/src/views/tap_p.rs b/src/views/tap_p.rs deleted file mode 100644 index 13c3c8d..0000000 --- a/src/views/tap_p.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::*; -use std::any::Any; - -/// Struct for the `tap` gesture. -pub struct TapP { - /// Child view tree. - child: V, - - /// Called when a tap occurs. - func: F, -} - -impl TapP -where - V: View, - F: Fn(&mut Context, LocalPoint, Option) -> A + 'static, -{ - pub fn new(v: V, f: F) -> Self { - Self { child: v, func: f } - } -} - -impl View for TapP -where - V: View, - F: Fn(&mut Context, LocalPoint, Option) -> A + 'static, - A: 'static, -{ - fn process( - &self, - event: &Event, - path: &mut IdPath, - cx: &mut Context, - actions: &mut Vec>, - ) { - let vid = cx.view_id(path); - match &event { - Event::TouchBegin { id, position } => { - if self.hittest(path, *position, cx).is_some() { - cx.touches[*id] = vid; - } - } - Event::TouchEnd { id, position } => { - if cx.touches[*id] == vid { - cx.touches[*id] = ViewId::default(); - actions.push(Box::new((self.func)(cx, *position, cx.mouse_button))) - } - } - _ => (), - } - } - - fn draw(&self, path: &mut IdPath, args: &mut DrawArgs) { - path.push(0); - self.child.draw(path, args); - path.pop(); - } - - fn layout(&self, path: &mut IdPath, args: &mut LayoutArgs) -> LocalSize { - path.push(0); - let sz = self.child.layout(path, args); - path.pop(); - sz - } - - fn hittest(&self, path: &mut IdPath, pt: LocalPoint, cx: &mut Context) -> Option { - path.push(0); - let id = self.child.hittest(path, pt, cx); - path.pop(); - id - } - - fn commands(&self, path: &mut IdPath, cx: &mut Context, cmds: &mut Vec) { - path.push(0); - self.child.commands(path, cx, cmds); - path.pop(); - } - - fn gc(&self, path: &mut IdPath, cx: &mut Context, map: &mut Vec) { - path.push(0); - self.child.gc(path, cx, map); - path.pop(); - } - - fn access( - &self, - path: &mut IdPath, - cx: &mut Context, - nodes: &mut Vec<(accesskit::NodeId, accesskit::Node)>, - ) -> Option { - path.push(0); - let node_id = self.child.access(path, cx, nodes); - path.pop(); - node_id - } -} - -impl private::Sealed for TapP where V: View {}