use teksilo_core::event::EventResponse;
use teksilo_core::overscroll::SCROLL_MOVE_EPSILON;
pub(crate) fn scroll_clamp_axis(base: f32, delta: f32, max: f32) -> (f32, bool) {
let new_pos = (base + delta).clamp(0.0, max);
let moved = (new_pos - base).abs() > SCROLL_MOVE_EPSILON;
(new_pos, moved)
}
pub(crate) fn scroll_response(moved_any: bool, contain: bool) -> EventResponse {
if contain || moved_any {
EventResponse::Handled
} else {
EventResponse::Ignored
}
}
pub use teksilo_core::OverscrollBehavior;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn clamp_axis_moves_within_range() {
let (pos, moved) = scroll_clamp_axis(10.0, 5.0, 100.0);
assert_eq!(pos, 15.0);
assert!(moved);
}
#[test]
fn clamp_axis_at_max_does_not_move() {
let (pos, moved) = scroll_clamp_axis(100.0, 20.0, 100.0);
assert_eq!(pos, 100.0);
assert!(!moved);
}
#[test]
fn clamp_axis_at_min_does_not_move() {
let (pos, moved) = scroll_clamp_axis(0.0, -20.0, 100.0);
assert_eq!(pos, 0.0);
assert!(!moved);
}
#[test]
fn clamp_axis_partial_consume_still_moves() {
let (pos, moved) = scroll_clamp_axis(95.0, 20.0, 100.0);
assert_eq!(pos, 100.0);
assert!(moved);
}
#[test]
fn response_chains_only_when_not_moved() {
assert!(matches!(
scroll_response(false, false),
EventResponse::Ignored
));
assert!(matches!(
scroll_response(true, false),
EventResponse::Handled
));
}
#[test]
fn response_contain_always_handled() {
assert!(matches!(
scroll_response(false, true),
EventResponse::Handled
));
assert!(matches!(
scroll_response(true, true),
EventResponse::Handled
));
}
}