use crate::pointer_tests_base::{
create_input_root, create_pointer_device_mock, create_top_level_impl_mock, raw_pointer_moved, MockHitTester,
};
use crate::testing::{TestServices, UnitTestApplication, UnitTestApplicationScope};
use crate::{Border, Window};
use ferroui_base::input::{InputElement, InputManager, KeyModifiers, PointerEventArgs, PointerPointProperties};
use ferroui_base::{PixelPoint, Point, Ref};
use std::cell::Cell;
use std::rc::Rc;
struct CrossTreePositionRequest {
pointer_event: Rc<PointerEventArgs>,
element_a: Ref<Border>,
element_b: Ref<Border>,
root1: Ref<Window>,
root2: Ref<Window>,
_app: UnitTestApplicationScope,
}
fn setup_cross_tree_position_request(top_level_position: PixelPoint) -> CrossTreePositionRequest {
let app = UnitTestApplication::start(TestServices::new().with_input_manager(Rc::new(InputManager::new())));
let renderer = Rc::new(MockHitTester::default());
let device = create_pointer_device_mock();
let impl1 = create_top_level_impl_mock();
impl1.position.set(top_level_position);
let element_a = Border::new();
let received = Rc::new(Cell::new(std::ptr::null::<PointerEventArgs>()));
let recorded = received.clone();
element_a.pointer_moved(move |_, e| recorded.set(e));
let root1 = create_input_root(&impl1, &element_a, &renderer);
let pointer_event = Rc::new(PointerEventArgs::new(
Some(InputElement::pointer_moved_event()),
&element_a,
device.pointer(),
Some(&root1.input_root().root_element()),
Point::default(),
0,
PointerPointProperties::NONE,
KeyModifiers::NONE,
));
let (raised, target) = (pointer_event.clone(), element_a.clone());
device.setup_process_raw_event(move || target.raise_event(&*raised));
raw_pointer_moved(&impl1, &device, &root1, Point::default());
assert!(std::ptr::eq(received.get(), Rc::as_ptr(&pointer_event)));
let impl2 = create_top_level_impl_mock();
let element_b = Border::new();
let root2 = create_input_root(&impl2, &element_b, &renderer);
assert_eq!(top_level_position.to_point(1.0), pointer_event.get_position(Some(&element_b)));
CrossTreePositionRequest { pointer_event, element_a, element_b, root1, root2, _app: app }
}
#[test]
fn get_position_should_return_default_when_cross_tree_source_closed() {
let top_level_offset = PixelPoint::new(5, 0);
let request = setup_cross_tree_position_request(top_level_offset);
assert!(request.element_a.presentation_source().is_some());
request.root1.presentation_source().dispose();
assert_eq!(Point::default(), request.pointer_event.get_position(Some(&request.element_b)));
}
#[test]
fn get_position_should_return_default_when_cross_tree_target_closed() {
let top_level_offset = PixelPoint::new(5, 0);
let request = setup_cross_tree_position_request(top_level_offset);
assert!(request.element_b.presentation_source().is_some());
request.root2.presentation_source().dispose();
assert_eq!(Point::default(), request.pointer_event.get_position(Some(&request.element_b)));
}