1use super::gesture_recognizers::GestureRecognizerCollection;
2use super::text_input::TextInputMethodClientRequestedEventArgs;
3use super::{
4 AccessKeyHandler, KeyBinding,
5 ContextRequestedEventArgs, Cursor, ICustomKeyboardNavigation, IScrollable, FocusChangedEventArgs, FocusChangingEventArgs, FocusManager, Gestures,
6 HoldingRoutedEventArgs, IInputElement, KeyEventArgs, KeyModifiers, KeyboardNavigation, NavigationMethod,
7 PointerCaptureChangingEventArgs, PointerCaptureLostEventArgs, PointerEventArgs, PointerPressedEventArgs,
8 PointerReleasedEventArgs, PointerWheelEventArgs, TappedEventArgs, TextInputEventArgs,
9};
10use crate::interactivity::{
11 IRoutedEventArgs, Interactive, InteractiveImpl, RoutedEvent, RoutedEventArgs, RoutedEventHandlerToken,
12 RoutingStrategies,
13};
14use crate::layout::LayoutableImpl;
15use crate::visual_tree::IHostedVisualTreeRoot;
16use crate::{
17 ferro_class, ferro_impl_classes, ferro_property, ferro_routed_event, instantiate, DirectProperty,
18 FerroObjectImpl, FerroObjectImplExt, FerroProperty, FerroPropertyChangedEventArgs, Ref, StyledElementImpl,
19 StyledProperty, StyledPropertyOptions, Visual, VisualImpl, VisualImplExt, VisualTreeAttachmentEventArgs,
20};
21use crate::collections::FerroList;
22use std::cell::{Cell, OnceCell};
23use std::rc::Rc;
24
25#[repr(C)]
31pub struct InputElement {
32 base: Interactive,
33 is_effectively_enabled: Cell<bool>,
34 is_focused: Cell<bool>,
35 is_keyboard_focus_within: Cell<bool>,
36 is_focus_visible: Cell<bool>,
37 is_pointer_over: Cell<bool>,
38 pub(super) is_context_menu_on_holding: Cell<bool>,
39 key_bindings: OnceCell<FerroList<Ref<KeyBinding>>>,
40 gesture_recognizers: OnceCell<GestureRecognizerCollection>,
41}
42
43ferro_class! {
44 InputElement: Interactive, virtuals InputElementImpl: InteractiveImpl {
45 fn is_enabled_core(this) -> bool;
50 fn is_focus_scope(this) -> bool;
53 fn on_getting_focus(this, e: &FocusChangingEventArgs);
56 fn on_losing_focus(this, e: &FocusChangingEventArgs);
59 fn on_got_focus(this, e: &FocusChangedEventArgs);
61 fn on_lost_focus(this, e: &FocusChangedEventArgs);
64 fn on_key_down(this, e: &KeyEventArgs);
66 fn on_key_up(this, e: &KeyEventArgs);
68 fn on_text_input(this, e: &TextInputEventArgs);
70 fn on_pointer_entered(this, e: &PointerEventArgs);
72 fn on_pointer_exited(this, e: &PointerEventArgs);
74 fn on_pointer_moved(this, e: &PointerEventArgs);
76 fn on_pointer_pressed(this, e: &PointerPressedEventArgs);
78 fn on_pointer_released(this, e: &PointerReleasedEventArgs);
80 fn on_pointer_capture_changing(this, e: &PointerCaptureChangingEventArgs);
83 fn on_pointer_capture_lost(this, e: &PointerCaptureLostEventArgs);
85 fn on_pointer_wheel_changed(this, e: &PointerWheelEventArgs);
87 fn on_tapped(this, e: &TappedEventArgs);
89 fn on_right_tapped(this, e: &TappedEventArgs);
91 fn on_double_tapped(this, e: &TappedEventArgs);
93 fn on_holding(this, e: &HoldingRoutedEventArgs);
95 fn on_access_key(this, e: &dyn IRoutedEventArgs);
98 fn get_next_tab_stop_override(this) -> Option<Ref<InputElement>>;
101 fn get_previous_tab_stop_override(this) -> Option<Ref<InputElement>>;
104 fn get_first_focusable_element_override(this) -> Option<Ref<InputElement>>;
106 fn get_last_focusable_element_override(this) -> Option<Ref<InputElement>>;
108 fn process_tab_stop_override(
112 this,
113 focused_element: Option<&Ref<InputElement>>,
114 candidate_tab_stop_element: Option<&Ref<InputElement>>,
115 is_reverse: bool,
116 did_cycle_focus_at_root_visual: bool,
117 new_tab_stop: &mut Option<Ref<InputElement>>
118 ) -> bool;
119 fn process_candidate_tab_stop_override(
124 this,
125 focused_element: Option<&Ref<InputElement>>,
126 candidate_tab_stop_element: Option<&Ref<InputElement>>,
127 overriden_candidate_tab_stop_element: Option<&Ref<InputElement>>,
128 is_reverse: bool,
129 new_tab_stop: &mut Option<Ref<InputElement>>
130 ) -> bool;
131 fn children_in_tab_focus_order(this) -> Option<Vec<Ref<InputElement>>>;
140 fn as_custom_keyboard_navigation(this) -> Option<&dyn ICustomKeyboardNavigation>;
143 fn as_scrollable(this) -> Option<&dyn IScrollable>;
145 fn as_hosted_visual_tree_root(this) -> Option<&dyn IHostedVisualTreeRoot>;
148 }
149}
150crate::ferro_class_info!(InputElement { new: InputElement::new });
151
152ferro_impl_classes!(InputElement: StyledElementImpl, LayoutableImpl, InteractiveImpl);
153
154crate::ferro_overrides! { impl FerroObjectImpl for InputElement {
155 fn constructed(this: &Self) {
156 Self::parent_constructed(this);
157 this.update_pseudo_classes(Some(this.is_focused()), Some(this.is_pointer_over()));
158 }
159
160 fn on_property_changed(this: &Self, change: &FerroPropertyChangedEventArgs<'_>) {
161 Self::parent_on_property_changed(this, change);
162
163 let property = change.property();
164
165 if property == Self::is_focused_property().as_property() {
166 this.update_pseudo_classes(Some(change.get_new_value::<bool>()), None);
167 } else if property == Self::is_pointer_over_property().as_property() {
168 this.update_pseudo_classes(None, Some(change.get_new_value::<bool>()));
169 } else if property == Self::is_keyboard_focus_within_property().as_property() {
170 this.pseudo_classes().set(":focus-within", change.get_new_value::<bool>());
171 } else if property == Visual::is_visible_property().as_property()
172 && !change.get_new_value::<bool>()
173 && this.is_keyboard_focus_within()
174 {
175 if let Some(focus_manager) = FocusManager::get_focus_manager(this) {
176 match (focus_manager.get_focused_element(), this.visual_parent()) {
177 (Some(focused_element), Some(visual_parent)) => {
178 focus_manager.clear_focus_on_element_removed(&focused_element, &visual_parent);
179 }
180 _ => {
181 focus_manager.focus(None, NavigationMethod::Unspecified, KeyModifiers::NONE);
182 }
183 }
184 }
185 }
186 }
187} }
188
189impl VisualImpl for InputElement {
190 fn on_detached_from_visual_tree_core(this: &Self, e: &VisualTreeAttachmentEventArgs) {
191 Self::parent_on_detached_from_visual_tree_core(this, e);
192
193 if this.is_focused() {
194 let root = e.attachment_point().unwrap_or(e.root_visual());
195 let focus_manager = e
196 .presentation_source()
197 .input_root()
198 .focus_manager()
199 .or_else(|| FocusManager::get_focus_manager(this));
200
201 if let Some(focus_manager) = focus_manager {
202 focus_manager.clear_focus_on_element_removed(this, root);
203 }
204 }
205
206 this.set_is_keyboard_focus_within(false);
207 }
208
209 fn on_attached_to_visual_tree_core(this: &Self, e: &VisualTreeAttachmentEventArgs) {
210 Self::parent_on_attached_to_visual_tree_core(this, e);
211 this.update_is_effectively_enabled();
212 }
213}
214
215impl InputElementImpl for InputElement {
216 fn is_enabled_core(this: &Self) -> bool {
217 this.is_enabled()
218 }
219
220 fn is_focus_scope(_this: &Self) -> bool {
221 false
222 }
223
224 fn on_getting_focus(_this: &Self, _e: &FocusChangingEventArgs) {}
225
226 fn on_losing_focus(_this: &Self, _e: &FocusChangingEventArgs) {}
227
228 fn on_got_focus(_this: &Self, _e: &FocusChangedEventArgs) {}
229
230 fn on_lost_focus(_this: &Self, _e: &FocusChangedEventArgs) {}
231
232 fn on_key_down(_this: &Self, _e: &KeyEventArgs) {}
233
234 fn on_key_up(_this: &Self, _e: &KeyEventArgs) {}
235
236 fn on_text_input(_this: &Self, _e: &TextInputEventArgs) {}
237
238 fn on_pointer_entered(_this: &Self, _e: &PointerEventArgs) {}
239
240 fn on_pointer_exited(_this: &Self, _e: &PointerEventArgs) {}
241
242 fn on_pointer_moved(_this: &Self, _e: &PointerEventArgs) {}
243
244 fn on_pointer_pressed(_this: &Self, _e: &PointerPressedEventArgs) {}
245
246 fn on_pointer_released(_this: &Self, _e: &PointerReleasedEventArgs) {}
247
248 fn on_pointer_capture_changing(_this: &Self, _e: &PointerCaptureChangingEventArgs) {}
249
250 fn on_pointer_capture_lost(_this: &Self, _e: &PointerCaptureLostEventArgs) {}
251
252 fn on_pointer_wheel_changed(_this: &Self, _e: &PointerWheelEventArgs) {}
253
254 fn on_tapped(_this: &Self, _e: &TappedEventArgs) {}
255
256 fn on_right_tapped(_this: &Self, _e: &TappedEventArgs) {}
257
258 fn on_double_tapped(_this: &Self, _e: &TappedEventArgs) {}
259
260 fn on_holding(_this: &Self, _e: &HoldingRoutedEventArgs) {}
261
262 fn on_access_key(this: &Self, _e: &dyn IRoutedEventArgs) {
263 this.focus_with(NavigationMethod::Tab, KeyModifiers::NONE);
264 }
265
266 fn get_next_tab_stop_override(_this: &Self) -> Option<Ref<InputElement>> {
267 None
268 }
269
270 fn get_previous_tab_stop_override(_this: &Self) -> Option<Ref<InputElement>> {
271 None
272 }
273
274 fn get_first_focusable_element_override(_this: &Self) -> Option<Ref<InputElement>> {
275 None
276 }
277
278 fn get_last_focusable_element_override(_this: &Self) -> Option<Ref<InputElement>> {
279 None
280 }
281
282 fn process_tab_stop_override(
283 _this: &Self,
284 _focused_element: Option<&Ref<InputElement>>,
285 _candidate_tab_stop_element: Option<&Ref<InputElement>>,
286 _is_reverse: bool,
287 _did_cycle_focus_at_root_visual: bool,
288 _new_tab_stop: &mut Option<Ref<InputElement>>,
289 ) -> bool {
290 false
291 }
292
293 fn process_candidate_tab_stop_override(
294 _this: &Self,
295 _focused_element: Option<&Ref<InputElement>>,
296 _candidate_tab_stop_element: Option<&Ref<InputElement>>,
297 _overriden_candidate_tab_stop_element: Option<&Ref<InputElement>>,
298 _is_reverse: bool,
299 _new_tab_stop: &mut Option<Ref<InputElement>>,
300 ) -> bool {
301 false
302 }
303
304 fn children_in_tab_focus_order(_this: &Self) -> Option<Vec<Ref<InputElement>>> {
305 None
306 }
307
308 fn as_custom_keyboard_navigation(_this: &Self) -> Option<&dyn ICustomKeyboardNavigation> {
309 None
310 }
311
312 fn as_scrollable(_this: &Self) -> Option<&dyn IScrollable> {
313 None
314 }
315
316 fn as_hosted_visual_tree_root(_this: &Self) -> Option<&dyn IHostedVisualTreeRoot> {
317 None
318 }
319}
320
321macro_rules! routed_event_accessor {
324 ($(#[$meta:meta])* $name:ident, $event:ident, $args:ty) => {
325 $(#[$meta])*
326 pub fn $name(&self, handler: impl Fn(&Interactive, &$args) + 'static) -> RoutedEventHandlerToken {
327 self.add_handler(Self::$event(), handler)
328 }
329 };
330}
331
332pub(super) use routed_event_accessor;
333
334crate::ferro_properties! { impl InputElement, also [InputElement::register_gesture_properties] {
335 ferro_property!(
338 pub fn focusable_property() -> StyledProperty<bool> {
340 FerroProperty::register::<InputElement, _>("Focusable", false)
341 }
342 );
343
344 ferro_property!(
345 pub fn is_enabled_property() -> StyledProperty<bool> {
347 FerroProperty::register::<InputElement, _>("IsEnabled", true)
348 }
349 );
350
351 ferro_property!(
352 pub fn is_effectively_enabled_property() -> DirectProperty<InputElement, bool> {
354 FerroProperty::register_direct::<InputElement, _>(
355 "IsEffectivelyEnabled",
356 |o| o.is_effectively_enabled(),
357 None,
358 false,
359 )
360 }
361 );
362
363 ferro_property!(
364 pub fn cursor_property() -> StyledProperty<Option<Rc<Cursor>>> {
366 FerroProperty::register_with::<InputElement, _>("Cursor", StyledPropertyOptions::new(None).inherits(true))
367 }
368 );
369
370 ferro_property!(
371 pub fn is_keyboard_focus_within_property() -> DirectProperty<InputElement, bool> {
373 FerroProperty::register_direct::<InputElement, _>(
374 "IsKeyboardFocusWithin",
375 |o| o.is_keyboard_focus_within(),
376 None,
377 false,
378 )
379 }
380 );
381
382 ferro_property!(
383 pub fn is_focused_property() -> DirectProperty<InputElement, bool> {
385 FerroProperty::register_direct::<InputElement, _>("IsFocused", |o| o.is_focused(), None, false)
386 }
387 );
388
389 ferro_property!(
390 pub fn is_hit_test_visible_property() -> StyledProperty<bool> {
392 FerroProperty::register::<InputElement, _>("IsHitTestVisible", true)
393 }
394 );
395
396 ferro_property!(
397 pub fn is_pointer_over_property() -> DirectProperty<InputElement, bool> {
399 FerroProperty::register_direct::<InputElement, _>("IsPointerOver", |o| o.is_pointer_over(), None, false)
400 }
401 );
402
403 ferro_property!(
404 pub fn is_tab_stop_property() -> StyledProperty<bool> {
406 KeyboardNavigation::is_tab_stop_property().add_owner::<InputElement>()
407 }
408 );
409
410 ferro_property!(
411 pub fn tab_index_property() -> StyledProperty<i32> {
413 KeyboardNavigation::tab_index_property().add_owner::<InputElement>()
414 }
415 );
416} }
417
418impl InputElement {
419 ferro_routed_event!(
422 pub fn got_focus_event() -> RoutedEvent<FocusChangedEventArgs> {
424 RoutedEvent::register::<InputElement, _>("GotFocus", RoutingStrategies::BUBBLE)
425 }
426 );
427
428 ferro_routed_event!(
429 pub fn getting_focus_event() -> RoutedEvent<FocusChangingEventArgs> {
431 RoutedEvent::register::<InputElement, _>("GettingFocus", RoutingStrategies::BUBBLE)
432 }
433 );
434
435 ferro_routed_event!(
436 pub fn lost_focus_event() -> RoutedEvent<FocusChangedEventArgs> {
438 RoutedEvent::register::<InputElement, _>("LostFocus", RoutingStrategies::BUBBLE)
439 }
440 );
441
442 ferro_routed_event!(
443 pub fn losing_focus_event() -> RoutedEvent<FocusChangingEventArgs> {
445 RoutedEvent::register::<InputElement, _>("LosingFocus", RoutingStrategies::BUBBLE)
446 }
447 );
448
449 ferro_routed_event!(
450 pub fn key_down_event() -> RoutedEvent<KeyEventArgs> {
452 RoutedEvent::register::<InputElement, _>("KeyDown", RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE)
453 }
454 );
455
456 ferro_routed_event!(
457 pub fn key_up_event() -> RoutedEvent<KeyEventArgs> {
459 RoutedEvent::register::<InputElement, _>("KeyUp", RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE)
460 }
461 );
462
463 ferro_routed_event!(
464 pub fn text_input_event() -> RoutedEvent<TextInputEventArgs> {
466 RoutedEvent::register::<InputElement, _>(
467 "TextInput",
468 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
469 )
470 }
471 );
472
473 ferro_routed_event!(
474 pub fn text_input_method_client_requested_event() -> RoutedEvent<TextInputMethodClientRequestedEventArgs> {
476 RoutedEvent::register::<InputElement, _>(
477 "TextInputMethodClientRequested",
478 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
479 )
480 }
481 );
482
483 ferro_routed_event!(
484 pub fn pointer_entered_event() -> RoutedEvent<PointerEventArgs> {
486 RoutedEvent::register::<InputElement, _>("PointerEntered", RoutingStrategies::DIRECT)
487 }
488 );
489
490 ferro_routed_event!(
491 pub fn pointer_exited_event() -> RoutedEvent<PointerEventArgs> {
493 RoutedEvent::register::<InputElement, _>("PointerExited", RoutingStrategies::DIRECT)
494 }
495 );
496
497 ferro_routed_event!(
498 pub fn pointer_moved_event() -> RoutedEvent<PointerEventArgs> {
500 RoutedEvent::register::<InputElement, _>(
501 "PointerMoved",
502 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
503 )
504 }
505 );
506
507 ferro_routed_event!(
508 pub fn pointer_pressed_event() -> RoutedEvent<PointerPressedEventArgs> {
510 RoutedEvent::register::<InputElement, _>(
511 "PointerPressed",
512 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
513 )
514 }
515 );
516
517 ferro_routed_event!(
518 pub fn pointer_released_event() -> RoutedEvent<PointerReleasedEventArgs> {
520 RoutedEvent::register::<InputElement, _>(
521 "PointerReleased",
522 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
523 )
524 }
525 );
526
527 ferro_routed_event!(
528 pub fn pointer_capture_changing_event() -> RoutedEvent<PointerCaptureChangingEventArgs> {
530 RoutedEvent::register::<InputElement, _>("PointerCaptureChanging", RoutingStrategies::DIRECT)
531 }
532 );
533
534 ferro_routed_event!(
535 pub fn pointer_capture_lost_event() -> RoutedEvent<PointerCaptureLostEventArgs> {
537 RoutedEvent::register::<InputElement, _>("PointerCaptureLost", RoutingStrategies::DIRECT)
538 }
539 );
540
541 ferro_routed_event!(
542 pub fn pointer_wheel_changed_event() -> RoutedEvent<PointerWheelEventArgs> {
544 RoutedEvent::register::<InputElement, _>(
545 "PointerWheelChanged",
546 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
547 )
548 }
549 );
550
551 ferro_routed_event!(
552 pub fn context_requested_event() -> RoutedEvent<ContextRequestedEventArgs> {
554 RoutedEvent::register::<InputElement, _>(
555 "ContextRequested",
556 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
557 )
558 }
559 );
560
561 ferro_routed_event!(
562 pub fn context_canceled_event() -> RoutedEvent<RoutedEventArgs> {
564 RoutedEvent::register::<InputElement, _>(
565 "ContextCanceled",
566 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
567 )
568 }
569 );
570
571 fn static_constructor() {
575 Self::context_requested_event();
579 Self::context_canceled_event();
580 Self::register_gesture_events();
581
582 Self::is_enabled_property().changed().subscribe(|e| {
583 if let Some(sender) = e.sender().downcast_ref::<InputElement>() {
584 sender.update_is_effectively_enabled();
585 }
586 });
587
588 Self::got_focus_event().add_class_handler::<InputElement>(|x, e| x.on_got_focus_core(e));
589 Self::lost_focus_event().add_class_handler::<InputElement>(|x, e| x.on_lost_focus_core(e));
590 Self::getting_focus_event().add_class_handler::<InputElement>(|x, e| x.on_getting_focus(e));
591 Self::losing_focus_event().add_class_handler::<InputElement>(|x, e| x.on_losing_focus(e));
592 Self::key_down_event().add_class_handler::<InputElement>(|x, e| x.on_key_down(e));
593 Self::key_up_event().add_class_handler::<InputElement>(|x, e| x.on_key_up(e));
594 Self::text_input_event().add_class_handler::<InputElement>(|x, e| x.on_text_input(e));
595 Self::pointer_entered_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_entered_core(e));
596 Self::pointer_exited_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_exited_core(e));
597 Self::pointer_moved_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_moved(e));
598 Self::pointer_pressed_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_pressed(e));
599 Self::pointer_released_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_released(e));
600 Self::pointer_capture_changing_event()
601 .add_class_handler::<InputElement>(|x, e| x.on_pointer_capture_changing(e));
602 Self::pointer_capture_lost_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_capture_lost(e));
603 Self::pointer_wheel_changed_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_wheel_changed(e));
604 Self::tapped_event().add_class_handler::<InputElement>(|x, e| x.on_tapped(e));
605 Self::right_tapped_event().add_class_handler::<InputElement>(|x, e| x.on_right_tapped(e));
606 Self::double_tapped_event().add_class_handler::<InputElement>(|x, e| x.on_double_tapped(e));
607 Self::holding_event().add_class_handler::<InputElement>(|x, e| x.on_holding(e));
608
609 Gestures::TYPE.ensure_class_init();
610 Gestures::add_tapped(|s, e| {
611 if s.is::<InputElement>() {
612 s.raise_event(e);
613 }
614 });
615 Gestures::add_right_tapped(|s, e| {
616 if s.is::<InputElement>() {
617 s.raise_event(e);
618 }
619 });
620 Gestures::add_double_tapped(|s, e| {
621 if s.is::<InputElement>() {
622 s.raise_event(e);
623 }
624 });
625 Gestures::add_holding(Self::on_preview_holding);
626
627 AccessKeyHandler::access_key_event().add_class_handler::<InputElement>(|x, e| x.on_access_key(e));
629
630 Self::pointer_moved_event().add_class_handler_with::<InputElement>(
632 |x, e| x.on_gesture_pointer_moved(e),
633 Interactive::DEFAULT_ROUTES,
634 true,
635 );
636 Self::pointer_pressed_event().add_class_handler_with::<InputElement>(
637 |x, e| x.on_gesture_pointer_pressed(e),
638 Interactive::DEFAULT_ROUTES,
639 true,
640 );
641 Self::pointer_released_event().add_class_handler_with::<InputElement>(
642 |x, e| x.on_gesture_pointer_released(e),
643 Interactive::DEFAULT_ROUTES,
644 true,
645 );
646 Self::pointer_capture_lost_event().add_class_handler_with::<InputElement>(
647 |x, e| x.on_gesture_pointer_capture_lost(e),
648 Interactive::DEFAULT_ROUTES,
649 true,
650 );
651 }
652
653 pub fn construct() -> Self {
655 Self {
656 base: Interactive::construct(),
657 is_effectively_enabled: Cell::new(true),
658 is_focused: Cell::new(false),
659 is_keyboard_focus_within: Cell::new(false),
660 is_focus_visible: Cell::new(false),
661 is_pointer_over: Cell::new(false),
662 is_context_menu_on_holding: Cell::new(false),
663 key_bindings: OnceCell::new(),
664 gesture_recognizers: OnceCell::new(),
665 }
666 }
667
668 pub fn new() -> Ref<Self> {
669 instantiate(Self::construct())
670 }
671
672 routed_event_accessor!(
675 got_focus, got_focus_event, FocusChangedEventArgs
677 );
678
679 routed_event_accessor!(
680 getting_focus, getting_focus_event, FocusChangingEventArgs
682 );
683
684 routed_event_accessor!(
685 lost_focus, lost_focus_event, FocusChangedEventArgs
687 );
688
689 routed_event_accessor!(
690 losing_focus, losing_focus_event, FocusChangingEventArgs
692 );
693
694 routed_event_accessor!(
695 key_down, key_down_event, KeyEventArgs
697 );
698
699 routed_event_accessor!(
700 key_up, key_up_event, KeyEventArgs
702 );
703
704 routed_event_accessor!(
705 text_input, text_input_event, TextInputEventArgs
707 );
708
709 routed_event_accessor!(
710 text_input_method_client_requested,
713 text_input_method_client_requested_event,
714 TextInputMethodClientRequestedEventArgs
715 );
716
717 routed_event_accessor!(
718 pointer_entered, pointer_entered_event, PointerEventArgs
720 );
721
722 routed_event_accessor!(
723 pointer_exited, pointer_exited_event, PointerEventArgs
725 );
726
727 routed_event_accessor!(
728 pointer_moved, pointer_moved_event, PointerEventArgs
730 );
731
732 routed_event_accessor!(
733 pointer_pressed, pointer_pressed_event, PointerPressedEventArgs
735 );
736
737 routed_event_accessor!(
738 pointer_released, pointer_released_event, PointerReleasedEventArgs
740 );
741
742 routed_event_accessor!(
743 pointer_capture_changing, pointer_capture_changing_event, PointerCaptureChangingEventArgs
746 );
747
748 routed_event_accessor!(
749 pointer_capture_lost, pointer_capture_lost_event, PointerCaptureLostEventArgs
754 );
755
756 routed_event_accessor!(
757 pointer_wheel_changed, pointer_wheel_changed_event, PointerWheelEventArgs
759 );
760
761 routed_event_accessor!(
762 context_requested, context_requested_event, ContextRequestedEventArgs
765 );
766
767 routed_event_accessor!(
768 context_canceled, context_canceled_event, RoutedEventArgs
772 );
773
774 pub fn focusable(&self) -> bool {
778 self.get_value(Self::focusable_property())
779 }
780
781 pub fn set_focusable(&self, value: bool) {
782 self.set_value(Self::focusable_property(), value)
783 }
784
785 pub fn is_enabled(&self) -> bool {
787 self.get_value(Self::is_enabled_property())
788 }
789
790 pub fn set_is_enabled(&self, value: bool) {
791 self.set_value(Self::is_enabled_property(), value)
792 }
793
794 pub fn cursor(&self) -> Option<Rc<Cursor>> {
796 self.get_value(Self::cursor_property())
797 }
798
799 pub fn set_cursor(&self, value: Option<Rc<Cursor>>) {
800 self.set_value(Self::cursor_property(), value)
801 }
802
803 #[inline]
806 pub fn is_keyboard_focus_within(&self) -> bool {
807 self.is_keyboard_focus_within.get()
808 }
809
810 pub(crate) fn set_is_keyboard_focus_within(&self, value: bool) {
811 self.set_and_raise_cell(Self::is_keyboard_focus_within_property(), &self.is_keyboard_focus_within, value);
812 }
813
814 #[inline]
816 pub fn is_focused(&self) -> bool {
817 self.is_focused.get()
818 }
819
820 fn set_is_focused(&self, value: bool) {
821 self.set_and_raise_cell(Self::is_focused_property(), &self.is_focused, value);
822 }
823
824 pub fn is_hit_test_visible(&self) -> bool {
826 self.get_value(Self::is_hit_test_visible_property())
827 }
828
829 pub fn set_is_hit_test_visible(&self, value: bool) {
830 self.set_value(Self::is_hit_test_visible_property(), value)
831 }
832
833 #[inline]
835 pub fn is_pointer_over(&self) -> bool {
836 self.is_pointer_over.get()
837 }
838
839 pub(crate) fn set_is_pointer_over(&self, value: bool) {
840 self.set_and_raise_cell(Self::is_pointer_over_property(), &self.is_pointer_over, value);
841 }
842
843 pub fn is_tab_stop(&self) -> bool {
845 self.get_value(Self::is_tab_stop_property())
846 }
847
848 pub fn set_is_tab_stop(&self, value: bool) {
849 self.set_value(Self::is_tab_stop_property(), value)
850 }
851
852 #[inline]
854 pub fn is_effectively_enabled(&self) -> bool {
855 self.is_effectively_enabled.get()
856 }
857
858 fn set_is_effectively_enabled(&self, value: bool) {
859 self.set_and_raise_cell(Self::is_effectively_enabled_property(), &self.is_effectively_enabled, value);
860 self.pseudo_classes().set(":disabled", !value);
861
862 if !self.is_effectively_enabled() {
863 if let Some(focus_manager) = FocusManager::get_focus_manager(self) {
864 let is_focused_element = focus_manager
865 .get_focused_element()
866 .is_some_and(|focused| std::ptr::eq::<InputElement>(&*focused, self));
867
868 if is_focused_element {
869 focus_manager.focus(None, NavigationMethod::Unspecified, KeyModifiers::NONE);
870 }
871 }
872 }
873 }
874
875 pub fn tab_index(&self) -> i32 {
878 self.get_value(Self::tab_index_property())
879 }
880
881 pub fn set_tab_index(&self, value: i32) {
882 self.set_value(Self::tab_index_property(), value)
883 }
884
885 pub fn key_bindings(&self) -> FerroList<Ref<KeyBinding>> {
889 self.key_bindings.get_or_init(FerroList::new).clone()
890 }
891
892 pub fn gesture_recognizers(&self) -> GestureRecognizerCollection {
894 self.gesture_recognizers.get_or_init(|| GestureRecognizerCollection::new(&self.to_ref())).clone()
895 }
896
897 fn on_gesture_pointer_released(&self, e: &PointerReleasedEventArgs) {
898 if !e.is_gesture_recognition_skipped() {
899 if let Some(recognizers) = self.gesture_recognizers.get() {
900 if recognizers.handle_pointer_released(e) {
901 e.set_handled(true);
902 }
903 }
904 }
905 }
906
907 fn on_gesture_pointer_capture_lost(&self, e: &PointerCaptureLostEventArgs) {
908 if let Some(recognizers) = self.gesture_recognizers.get() {
909 recognizers.handle_capture_lost(e.pointer());
910 }
911 }
912
913 fn on_gesture_pointer_pressed(&self, e: &PointerPressedEventArgs) {
914 if !e.is_gesture_recognition_skipped() {
915 if let Some(recognizers) = self.gesture_recognizers.get() {
916 if recognizers.handle_pointer_pressed(e) {
917 e.set_handled(true);
918 }
919 }
920 }
921 }
922
923 fn on_gesture_pointer_moved(&self, e: &PointerEventArgs) {
924 if !e.is_gesture_recognition_skipped() {
925 if let Some(recognizers) = self.gesture_recognizers.get() {
926 if recognizers.handle_pointer_moved(e) {
927 e.set_handled(true);
928 }
929 }
930 }
931 }
932
933 pub fn focus(&self) -> bool {
938 self.focus_with(NavigationMethod::Unspecified, KeyModifiers::NONE)
939 }
940
941 pub fn focus_with(&self, method: NavigationMethod, key_modifiers: KeyModifiers) -> bool {
947 match FocusManager::get_focus_manager(self) {
948 Some(focus_manager) => focus_manager.focus(Some(&self.to_ref()), method, key_modifiers),
949 None => false,
950 }
951 }
952
953 pub(crate) fn process_tab_stop(
957 _content_root: Option<&Ref<InputElement>>,
958 focused_element: Option<&Ref<InputElement>>,
959 candidate_tab_stop_element: Option<&Ref<InputElement>>,
960 is_reverse: bool,
961 did_cycle_focus_at_root_visual: bool,
962 ) -> (bool, Option<Ref<InputElement>>) {
963 let new_tab_stop: Option<Ref<InputElement>> = None;
966 let mut is_tab_stop_overridden = false;
967 let mut sp_new_tab_stop: Option<Ref<InputElement>> = None;
968
969 if let Some(focused) = focused_element {
970 let (overridden, tab_stop) = focused.process_tab_stop_internal(
971 candidate_tab_stop_element,
972 is_reverse,
973 did_cycle_focus_at_root_visual,
974 );
975 is_tab_stop_overridden = overridden;
976 sp_new_tab_stop = tab_stop;
977 }
978
979 if !is_tab_stop_overridden {
980 if let Some(candidate) = candidate_tab_stop_element {
981 let (overridden, tab_stop) =
982 candidate.process_candidate_tab_stop_internal(focused_element, None, is_reverse);
983 is_tab_stop_overridden = overridden;
984 sp_new_tab_stop = tab_stop;
985 }
986 }
987
988 let _ = sp_new_tab_stop;
992
993 (is_tab_stop_overridden, new_tab_stop)
994 }
995
996 fn process_tab_stop_internal(
997 &self,
998 candidate_tab_stop_element: Option<&Ref<InputElement>>,
999 is_reverse: bool,
1000 did_cycle_focus_at_root_visual: bool,
1001 ) -> (bool, Option<Ref<InputElement>>) {
1002 let this = self.to_ref();
1003 let mut current = Some(this.clone());
1004 let mut new_tab_stop = None;
1005 let mut candidate_tab_stop_overridden = false;
1006
1007 while let Some(c) = current {
1008 if candidate_tab_stop_overridden {
1009 break;
1010 }
1011
1012 candidate_tab_stop_overridden = c.process_tab_stop_override(
1013 Some(&this),
1014 candidate_tab_stop_element,
1015 is_reverse,
1016 did_cycle_focus_at_root_visual,
1017 &mut new_tab_stop,
1018 );
1019 current = c.parent().and_then(|parent| parent.downcast::<InputElement>().ok());
1020 }
1021
1022 (candidate_tab_stop_overridden, new_tab_stop)
1023 }
1024
1025 fn process_candidate_tab_stop_internal(
1026 &self,
1027 current_tab_stop: Option<&Ref<InputElement>>,
1028 overriden_candidate_tab_stop_element: Option<&Ref<InputElement>>,
1029 is_reverse: bool,
1030 ) -> (bool, Option<Ref<InputElement>>) {
1031 let this = self.to_ref();
1032 let mut current = Some(this.clone());
1033 let mut new_tab_stop = None;
1034 let mut candidate_tab_stop_overridden = false;
1035
1036 while let Some(c) = current {
1037 if candidate_tab_stop_overridden {
1038 break;
1039 }
1040
1041 candidate_tab_stop_overridden = c.process_candidate_tab_stop_override(
1042 current_tab_stop,
1043 Some(&this),
1044 overriden_candidate_tab_stop_element,
1045 is_reverse,
1046 &mut new_tab_stop,
1047 );
1048 current = c.parent().and_then(|parent| parent.downcast::<InputElement>().ok());
1049 }
1050
1051 (candidate_tab_stop_overridden, new_tab_stop)
1052 }
1053
1054 fn on_got_focus_core(&self, e: &FocusChangedEventArgs) {
1055 let is_focused = e.is_source(self);
1056 self.is_focus_visible.set(
1057 is_focused
1058 && (e.navigation_method == NavigationMethod::Directional
1059 || e.navigation_method == NavigationMethod::Tab),
1060 );
1061 self.set_is_focused(is_focused);
1062 self.on_got_focus(e);
1063 }
1064
1065 fn on_lost_focus_core(&self, e: &FocusChangedEventArgs) {
1066 self.is_focus_visible.set(false);
1067 self.set_is_focused(false);
1068 self.on_lost_focus(e);
1069 }
1070
1071 pub fn update_is_effectively_enabled(&self) {
1074 let parent = self.get_visual_parent_of_type::<InputElement>();
1075 self.update_is_effectively_enabled_from(parent.as_deref());
1076 }
1077
1078 fn on_pointer_entered_core(&self, e: &PointerEventArgs) {
1079 self.set_is_pointer_over(true);
1080 self.on_pointer_entered(e);
1081 }
1082
1083 fn on_pointer_exited_core(&self, e: &PointerEventArgs) {
1084 self.set_is_pointer_over(false);
1085 self.on_pointer_exited(e);
1086 }
1087
1088 fn update_is_effectively_enabled_from(&self, parent: Option<&InputElement>) {
1091 self.set_is_effectively_enabled(
1092 self.is_enabled_core() && parent.is_none_or(InputElement::is_effectively_enabled),
1093 );
1094
1095 if let Some(children) = self.visual_children_snapshot() {
1097 for child in children.iter() {
1098 if let Some(child) = child.downcast_ref::<InputElement>() {
1099 child.update_is_effectively_enabled_from(Some(self));
1100 }
1101 }
1102 }
1103 }
1104
1105 fn update_pseudo_classes(&self, is_focused: Option<bool>, is_pointer_over: Option<bool>) {
1106 if let Some(is_focused) = is_focused {
1107 self.pseudo_classes().set(":focus", is_focused);
1108 self.pseudo_classes().set(":focus-visible", self.is_focus_visible.get());
1109 }
1110
1111 if let Some(is_pointer_over) = is_pointer_over {
1112 self.pseudo_classes().set(":pointerover", is_pointer_over);
1113 }
1114 }
1115}
1116
1117impl IInputElement for InputElement {
1118 fn focusable(&self) -> bool {
1119 InputElement::focusable(self)
1120 }
1121
1122 fn is_enabled(&self) -> bool {
1123 InputElement::is_enabled(self)
1124 }
1125
1126 fn cursor(&self) -> Option<Rc<Cursor>> {
1127 InputElement::cursor(self)
1128 }
1129
1130 fn is_effectively_enabled(&self) -> bool {
1131 InputElement::is_effectively_enabled(self)
1132 }
1133
1134 fn is_effectively_visible(&self) -> bool {
1135 Visual::is_effectively_visible(self)
1136 }
1137
1138 fn is_keyboard_focus_within(&self) -> bool {
1139 InputElement::is_keyboard_focus_within(self)
1140 }
1141
1142 fn is_focused(&self) -> bool {
1143 InputElement::is_focused(self)
1144 }
1145
1146 fn is_hit_test_visible(&self) -> bool {
1147 InputElement::is_hit_test_visible(self)
1148 }
1149
1150 fn is_pointer_over(&self) -> bool {
1151 InputElement::is_pointer_over(self)
1152 }
1153
1154 fn focus(&self, method: NavigationMethod, key_modifiers: KeyModifiers) -> bool {
1155 InputElement::focus_with(self, method, key_modifiers)
1156 }
1157}