use agape_core::Position;
use agape_layout::Layout;
#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)]
pub struct CursorPosition {
current: Position,
previous: Position,
}
impl CursorPosition {
pub fn new() -> Self {
Self::default()
}
pub fn update(&mut self, position: Position) {
self.previous = self.current;
self.current = position;
}
pub fn current(&self) -> Position {
self.current
}
pub fn previous(&self) -> Position {
self.previous
}
pub fn mouse_entered(&self, layout: &dyn Layout) -> bool {
let bounds = layout.bounds();
!bounds.within(&self.previous) && bounds.within(&self.current)
}
pub fn mouse_left(&self, layout: &dyn Layout) -> bool {
let bounds = layout.bounds();
bounds.within(&self.previous) && !bounds.within(&self.current)
}
pub fn is_hovered(&self, layout: &dyn Layout) -> bool {
layout.bounds().within(&self.current)
}
}
#[cfg(test)]
mod test {
use super::*;
use agape_core::Size;
use agape_layout::{EmptyLayout, IntrinsicSize, solve_layout};
#[test]
fn just_hovered() {
let mut layout = EmptyLayout::new();
layout.intrinsic_size = IntrinsicSize::fixed(200.0, 50.0);
solve_layout(&mut layout, Size::unit(1000.0));
let mut cursor_pos = CursorPosition::new();
cursor_pos.current = Position::unit(10.0);
cursor_pos.previous = Position::unit(300.0);
assert!(cursor_pos.mouse_entered(&layout));
}
#[test]
fn mouse_left() {
let mut layout = EmptyLayout::new();
layout.intrinsic_size = IntrinsicSize::fixed(200.0, 50.0);
solve_layout(&mut layout, Size::unit(1000.0));
let mut cursor_pos = CursorPosition::new();
cursor_pos.previous = Position::unit(10.0);
cursor_pos.current = Position::unit(300.0);
assert!(cursor_pos.mouse_left(&layout));
}
#[test]
fn cursor_already_in_bounds() {
let mut layout = EmptyLayout::new();
layout.intrinsic_size = IntrinsicSize::fixed(200.0, 50.0);
solve_layout(&mut layout, Size::unit(1000.0));
let mut cursor_pos = CursorPosition::new();
cursor_pos.current = Position::unit(10.0);
cursor_pos.previous = Position::unit(40.0);
assert!(!cursor_pos.mouse_entered(&layout));
}
#[test]
fn not_hovered() {
let mut layout = EmptyLayout::new();
layout.intrinsic_size = IntrinsicSize::fixed(200.0, 50.0);
solve_layout(&mut layout, Size::unit(1000.0));
let mut cursor_pos = CursorPosition::new();
cursor_pos.current = Position::unit(350.0);
cursor_pos.previous = Position::unit(400.0);
assert!(!cursor_pos.mouse_entered(&layout));
}
}