ferroui_controls/presentation_source/
presentation_source_cursor.rs1use super::PresentationSource;
2use ferroui_base::input::text_input::ITextInputMethodImpl;
3use ferroui_base::input::{Cursor, FocusManager, IInputRoot, InputElement};
4use ferroui_base::platform::IOptionalFeatureProvider;
5use ferroui_base::{Point, Rect, Ref, Size};
6use std::rc::Rc;
7
8impl PresentationSource {
9 fn update_cursor(&self) {
10 let cursor = self.cursor_override.borrow().clone().or_else(|| self.cursor.borrow().clone());
11 if let Some(platform_impl) = self.platform_impl() {
12 platform_impl.set_cursor(cursor.map(|cursor| cursor.platform_impl().clone()));
13 }
14 }
15
16 fn set_cursor(&self, cursor: Option<Rc<Cursor>>) {
17 *self.cursor.borrow_mut() = cursor;
18 self.update_cursor();
19 }
20
21 pub fn set_cursor_override(&self, cursor: Option<Rc<Cursor>>) {
23 *self.cursor_override.borrow_mut() = cursor;
24 self.update_cursor();
25 }
26}
27
28impl IInputRoot for PresentationSource {
29 fn hit_test_chrome_element(&self, point: Point) -> Option<ferroui_base::input::WindowDecorationsElementRole> {
30 let root_visual = self.root_visual()?;
33 let visual = root_visual.get_visual_at_filtered(point, &PresentationSource::chrome_hit_test_filter);
34 PresentationSource::get_chrome_role_from_visual(visual)
35 }
36
37 fn focus_manager(&self) -> Option<Rc<FocusManager>> {
38 Some(PresentationSource::focus_manager(self).clone())
39 }
40
41 fn pointer_over_element(&self) -> Option<Ref<InputElement>> {
42 self.pointer_over_element.borrow().clone()
43 }
44
45 fn set_pointer_over_element(&self, value: Option<Ref<InputElement>>) {
46 let old = self.pointer_over_element.replace(value);
47 drop(old);
48 }
49
50 fn cursor_element(&self) -> Option<Ref<InputElement>> {
51 self.cursor_element.borrow().clone()
52 }
53
54 fn set_cursor_element(&self, value: Option<Ref<InputElement>>) {
55 if *self.cursor_element.borrow() == value {
56 return;
57 }
58
59 if let Some(subscription) = self.cursor_element_subscription.borrow_mut().take() {
60 subscription.dispose();
61 }
62 let old = self.cursor_element.replace(value.clone());
63 drop(old);
64 if let Some(new) = &value {
65 let weak = self.this.clone();
66 let element = new.downgrade();
67 let subscription = new.property_changed(move |e| {
68 if e.property() == InputElement::cursor_property().as_property() {
69 if let Some(source) = weak.upgrade() {
70 source.set_cursor(element.upgrade().and_then(|element| element.cursor()));
71 }
72 }
73 });
74 *self.cursor_element_subscription.borrow_mut() = Some(subscription);
75 }
76 self.set_cursor(value.and_then(|element| element.cursor()));
77 }
78
79 fn input_method(&self) -> Option<Rc<dyn ITextInputMethodImpl>> {
80 let platform_impl = self.platform_impl()?;
81 let provider: &dyn IOptionalFeatureProvider = &*platform_impl;
82 provider.try_get::<dyn ITextInputMethodImpl>()
83 }
84
85 fn root_element(&self) -> Ref<InputElement> {
86 PresentationSource::root_element(self)
87 }
88
89 fn try_root_element(&self) -> Option<Ref<InputElement>> {
90 self.root_visual()
91 }
92
93 fn focus_root(&self) -> Ref<InputElement> {
94 PresentationSource::focus_root(self)
95 }
96
97 fn pointer_over_invalidated(&self) {
98 let pre_processor = self.pointer_over_pre_processor.borrow().clone();
99 if let Some(pre_processor) = pre_processor {
100 pre_processor.scene_invalidated(Rect::from_position_size(Point::new(0.0, 0.0), Size::INFINITY));
101 }
102 }
103}