use std::sync::Arc;
use fret_core::MouseButton;
use fret_ui::action::{OnPinchGesture, OnPointerDown, OnWheel};
use fret_ui::element::{AnyElement, PointerRegionProps};
use fret_ui::{ElementContext, UiHost};
#[derive(Debug, Clone)]
pub struct CanvasInputExemptRegionProps {
pub pointer_region: PointerRegionProps,
pub block_wheel: bool,
pub block_pinch: bool,
pub block_pan_button: Option<MouseButton>,
}
impl Default for CanvasInputExemptRegionProps {
fn default() -> Self {
Self {
pointer_region: PointerRegionProps::default(),
block_wheel: true,
block_pinch: true,
block_pan_button: Some(MouseButton::Middle),
}
}
}
impl CanvasInputExemptRegionProps {
pub fn nowheel(mut self, block: bool) -> Self {
self.block_wheel = block;
self
}
pub fn nopan_middle(mut self, block: bool) -> Self {
self.block_pan_button = block.then_some(MouseButton::Middle);
self
}
}
#[track_caller]
pub fn canvas_input_exempt_region<H: UiHost, I>(
cx: &mut ElementContext<'_, H>,
props: CanvasInputExemptRegionProps,
f: impl FnOnce(&mut ElementContext<'_, H>) -> I,
) -> AnyElement
where
I: IntoIterator<Item = AnyElement>,
{
let block_wheel = props.block_wheel;
let block_pinch = props.block_pinch;
let block_pan_button = props.block_pan_button;
cx.pointer_region(props.pointer_region, move |cx| {
if block_wheel {
let on_wheel: OnWheel = Arc::new(move |_host, _cx, _wheel| true);
cx.pointer_region_on_wheel(on_wheel);
}
if block_pinch {
let on_pinch: OnPinchGesture = Arc::new(move |_host, _cx, _pinch| true);
cx.pointer_region_on_pinch_gesture(on_pinch);
}
if let Some(btn) = block_pan_button {
let on_down: OnPointerDown = Arc::new(move |_host, _cx, down| down.button == btn);
cx.pointer_region_add_on_pointer_down(on_down);
}
f(cx)
})
}