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 as_custom_keyboard_navigation(this) -> Option<&dyn ICustomKeyboardNavigation>;
134 fn as_scrollable(this) -> Option<&dyn IScrollable>;
136 fn as_hosted_visual_tree_root(this) -> Option<&dyn IHostedVisualTreeRoot>;
139 }
140}
141crate::ferro_class_info!(InputElement { new: InputElement::new });
142
143ferro_impl_classes!(InputElement: StyledElementImpl, LayoutableImpl, InteractiveImpl);
144
145crate::ferro_overrides! { impl FerroObjectImpl for InputElement {
146 fn constructed(this: &Self) {
147 Self::parent_constructed(this);
148 this.update_pseudo_classes(Some(this.is_focused()), Some(this.is_pointer_over()));
149 }
150
151 fn on_property_changed(this: &Self, change: &FerroPropertyChangedEventArgs<'_>) {
152 Self::parent_on_property_changed(this, change);
153
154 let property = change.property();
155
156 if property == Self::is_focused_property().as_property() {
157 this.update_pseudo_classes(Some(change.get_new_value::<bool>()), None);
158 } else if property == Self::is_pointer_over_property().as_property() {
159 this.update_pseudo_classes(None, Some(change.get_new_value::<bool>()));
160 } else if property == Self::is_keyboard_focus_within_property().as_property() {
161 this.pseudo_classes().set(":focus-within", change.get_new_value::<bool>());
162 } else if property == Visual::is_visible_property().as_property()
163 && !change.get_new_value::<bool>()
164 && this.is_keyboard_focus_within()
165 {
166 if let Some(focus_manager) = FocusManager::get_focus_manager(this) {
167 match (focus_manager.get_focused_element(), this.visual_parent()) {
168 (Some(focused_element), Some(visual_parent)) => {
169 focus_manager.clear_focus_on_element_removed(&focused_element, &visual_parent);
170 }
171 _ => {
172 focus_manager.focus(None, NavigationMethod::Unspecified, KeyModifiers::NONE);
173 }
174 }
175 }
176 }
177 }
178} }
179
180impl VisualImpl for InputElement {
181 fn on_detached_from_visual_tree_core(this: &Self, e: &VisualTreeAttachmentEventArgs) {
182 Self::parent_on_detached_from_visual_tree_core(this, e);
183
184 if this.is_focused() {
185 let root = e.attachment_point().unwrap_or(e.root_visual());
186 let focus_manager = e
187 .presentation_source()
188 .input_root()
189 .focus_manager()
190 .or_else(|| FocusManager::get_focus_manager(this));
191
192 if let Some(focus_manager) = focus_manager {
193 focus_manager.clear_focus_on_element_removed(this, root);
194 }
195 }
196
197 this.set_is_keyboard_focus_within(false);
198 }
199
200 fn on_attached_to_visual_tree_core(this: &Self, e: &VisualTreeAttachmentEventArgs) {
201 Self::parent_on_attached_to_visual_tree_core(this, e);
202 this.update_is_effectively_enabled();
203 }
204}
205
206impl InputElementImpl for InputElement {
207 fn is_enabled_core(this: &Self) -> bool {
208 this.is_enabled()
209 }
210
211 fn is_focus_scope(_this: &Self) -> bool {
212 false
213 }
214
215 fn on_getting_focus(_this: &Self, _e: &FocusChangingEventArgs) {}
216
217 fn on_losing_focus(_this: &Self, _e: &FocusChangingEventArgs) {}
218
219 fn on_got_focus(_this: &Self, _e: &FocusChangedEventArgs) {}
220
221 fn on_lost_focus(_this: &Self, _e: &FocusChangedEventArgs) {}
222
223 fn on_key_down(_this: &Self, _e: &KeyEventArgs) {}
224
225 fn on_key_up(_this: &Self, _e: &KeyEventArgs) {}
226
227 fn on_text_input(_this: &Self, _e: &TextInputEventArgs) {}
228
229 fn on_pointer_entered(_this: &Self, _e: &PointerEventArgs) {}
230
231 fn on_pointer_exited(_this: &Self, _e: &PointerEventArgs) {}
232
233 fn on_pointer_moved(_this: &Self, _e: &PointerEventArgs) {}
234
235 fn on_pointer_pressed(_this: &Self, _e: &PointerPressedEventArgs) {}
236
237 fn on_pointer_released(_this: &Self, _e: &PointerReleasedEventArgs) {}
238
239 fn on_pointer_capture_changing(_this: &Self, _e: &PointerCaptureChangingEventArgs) {}
240
241 fn on_pointer_capture_lost(_this: &Self, _e: &PointerCaptureLostEventArgs) {}
242
243 fn on_pointer_wheel_changed(_this: &Self, _e: &PointerWheelEventArgs) {}
244
245 fn on_tapped(_this: &Self, _e: &TappedEventArgs) {}
246
247 fn on_right_tapped(_this: &Self, _e: &TappedEventArgs) {}
248
249 fn on_double_tapped(_this: &Self, _e: &TappedEventArgs) {}
250
251 fn on_holding(_this: &Self, _e: &HoldingRoutedEventArgs) {}
252
253 fn on_access_key(this: &Self, _e: &dyn IRoutedEventArgs) {
254 this.focus_with(NavigationMethod::Tab, KeyModifiers::NONE);
255 }
256
257 fn get_next_tab_stop_override(_this: &Self) -> Option<Ref<InputElement>> {
258 None
259 }
260
261 fn get_previous_tab_stop_override(_this: &Self) -> Option<Ref<InputElement>> {
262 None
263 }
264
265 fn get_first_focusable_element_override(_this: &Self) -> Option<Ref<InputElement>> {
266 None
267 }
268
269 fn get_last_focusable_element_override(_this: &Self) -> Option<Ref<InputElement>> {
270 None
271 }
272
273 fn process_tab_stop_override(
274 _this: &Self,
275 _focused_element: Option<&Ref<InputElement>>,
276 _candidate_tab_stop_element: Option<&Ref<InputElement>>,
277 _is_reverse: bool,
278 _did_cycle_focus_at_root_visual: bool,
279 _new_tab_stop: &mut Option<Ref<InputElement>>,
280 ) -> bool {
281 false
282 }
283
284 fn process_candidate_tab_stop_override(
285 _this: &Self,
286 _focused_element: Option<&Ref<InputElement>>,
287 _candidate_tab_stop_element: Option<&Ref<InputElement>>,
288 _overriden_candidate_tab_stop_element: Option<&Ref<InputElement>>,
289 _is_reverse: bool,
290 _new_tab_stop: &mut Option<Ref<InputElement>>,
291 ) -> bool {
292 false
293 }
294
295 fn as_custom_keyboard_navigation(_this: &Self) -> Option<&dyn ICustomKeyboardNavigation> {
296 None
297 }
298
299 fn as_scrollable(_this: &Self) -> Option<&dyn IScrollable> {
300 None
301 }
302
303 fn as_hosted_visual_tree_root(_this: &Self) -> Option<&dyn IHostedVisualTreeRoot> {
304 None
305 }
306}
307
308macro_rules! routed_event_accessor {
311 ($(#[$meta:meta])* $name:ident, $event:ident, $args:ty) => {
312 $(#[$meta])*
313 pub fn $name(&self, handler: impl Fn(&Interactive, &$args) + 'static) -> RoutedEventHandlerToken {
314 self.add_handler(Self::$event(), handler)
315 }
316 };
317}
318
319pub(super) use routed_event_accessor;
320
321crate::ferro_properties! { impl InputElement, also [InputElement::register_gesture_properties] {
322 ferro_property!(
325 pub fn focusable_property() -> StyledProperty<bool> {
327 FerroProperty::register::<InputElement, _>("Focusable", false)
328 }
329 );
330
331 ferro_property!(
332 pub fn is_enabled_property() -> StyledProperty<bool> {
334 FerroProperty::register::<InputElement, _>("IsEnabled", true)
335 }
336 );
337
338 ferro_property!(
339 pub fn is_effectively_enabled_property() -> DirectProperty<InputElement, bool> {
341 FerroProperty::register_direct::<InputElement, _>(
342 "IsEffectivelyEnabled",
343 |o| o.is_effectively_enabled(),
344 None,
345 false,
346 )
347 }
348 );
349
350 ferro_property!(
351 pub fn cursor_property() -> StyledProperty<Option<Rc<Cursor>>> {
353 FerroProperty::register_with::<InputElement, _>("Cursor", StyledPropertyOptions::new(None).inherits(true))
354 }
355 );
356
357 ferro_property!(
358 pub fn is_keyboard_focus_within_property() -> DirectProperty<InputElement, bool> {
360 FerroProperty::register_direct::<InputElement, _>(
361 "IsKeyboardFocusWithin",
362 |o| o.is_keyboard_focus_within(),
363 None,
364 false,
365 )
366 }
367 );
368
369 ferro_property!(
370 pub fn is_focused_property() -> DirectProperty<InputElement, bool> {
372 FerroProperty::register_direct::<InputElement, _>("IsFocused", |o| o.is_focused(), None, false)
373 }
374 );
375
376 ferro_property!(
377 pub fn is_hit_test_visible_property() -> StyledProperty<bool> {
379 FerroProperty::register::<InputElement, _>("IsHitTestVisible", true)
380 }
381 );
382
383 ferro_property!(
384 pub fn is_pointer_over_property() -> DirectProperty<InputElement, bool> {
386 FerroProperty::register_direct::<InputElement, _>("IsPointerOver", |o| o.is_pointer_over(), None, false)
387 }
388 );
389
390 ferro_property!(
391 pub fn is_tab_stop_property() -> StyledProperty<bool> {
393 KeyboardNavigation::is_tab_stop_property().add_owner::<InputElement>()
394 }
395 );
396
397 ferro_property!(
398 pub fn tab_index_property() -> StyledProperty<i32> {
400 KeyboardNavigation::tab_index_property().add_owner::<InputElement>()
401 }
402 );
403} }
404
405impl InputElement {
406 ferro_routed_event!(
409 pub fn got_focus_event() -> RoutedEvent<FocusChangedEventArgs> {
411 RoutedEvent::register::<InputElement, _>("GotFocus", RoutingStrategies::BUBBLE)
412 }
413 );
414
415 ferro_routed_event!(
416 pub fn getting_focus_event() -> RoutedEvent<FocusChangingEventArgs> {
418 RoutedEvent::register::<InputElement, _>("GettingFocus", RoutingStrategies::BUBBLE)
419 }
420 );
421
422 ferro_routed_event!(
423 pub fn lost_focus_event() -> RoutedEvent<FocusChangedEventArgs> {
425 RoutedEvent::register::<InputElement, _>("LostFocus", RoutingStrategies::BUBBLE)
426 }
427 );
428
429 ferro_routed_event!(
430 pub fn losing_focus_event() -> RoutedEvent<FocusChangingEventArgs> {
432 RoutedEvent::register::<InputElement, _>("LosingFocus", RoutingStrategies::BUBBLE)
433 }
434 );
435
436 ferro_routed_event!(
437 pub fn key_down_event() -> RoutedEvent<KeyEventArgs> {
439 RoutedEvent::register::<InputElement, _>("KeyDown", RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE)
440 }
441 );
442
443 ferro_routed_event!(
444 pub fn key_up_event() -> RoutedEvent<KeyEventArgs> {
446 RoutedEvent::register::<InputElement, _>("KeyUp", RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE)
447 }
448 );
449
450 ferro_routed_event!(
451 pub fn text_input_event() -> RoutedEvent<TextInputEventArgs> {
453 RoutedEvent::register::<InputElement, _>(
454 "TextInput",
455 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
456 )
457 }
458 );
459
460 ferro_routed_event!(
461 pub fn text_input_method_client_requested_event() -> RoutedEvent<TextInputMethodClientRequestedEventArgs> {
463 RoutedEvent::register::<InputElement, _>(
464 "TextInputMethodClientRequested",
465 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
466 )
467 }
468 );
469
470 ferro_routed_event!(
471 pub fn pointer_entered_event() -> RoutedEvent<PointerEventArgs> {
473 RoutedEvent::register::<InputElement, _>("PointerEntered", RoutingStrategies::DIRECT)
474 }
475 );
476
477 ferro_routed_event!(
478 pub fn pointer_exited_event() -> RoutedEvent<PointerEventArgs> {
480 RoutedEvent::register::<InputElement, _>("PointerExited", RoutingStrategies::DIRECT)
481 }
482 );
483
484 ferro_routed_event!(
485 pub fn pointer_moved_event() -> RoutedEvent<PointerEventArgs> {
487 RoutedEvent::register::<InputElement, _>(
488 "PointerMoved",
489 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
490 )
491 }
492 );
493
494 ferro_routed_event!(
495 pub fn pointer_pressed_event() -> RoutedEvent<PointerPressedEventArgs> {
497 RoutedEvent::register::<InputElement, _>(
498 "PointerPressed",
499 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
500 )
501 }
502 );
503
504 ferro_routed_event!(
505 pub fn pointer_released_event() -> RoutedEvent<PointerReleasedEventArgs> {
507 RoutedEvent::register::<InputElement, _>(
508 "PointerReleased",
509 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
510 )
511 }
512 );
513
514 ferro_routed_event!(
515 pub fn pointer_capture_changing_event() -> RoutedEvent<PointerCaptureChangingEventArgs> {
517 RoutedEvent::register::<InputElement, _>("PointerCaptureChanging", RoutingStrategies::DIRECT)
518 }
519 );
520
521 ferro_routed_event!(
522 pub fn pointer_capture_lost_event() -> RoutedEvent<PointerCaptureLostEventArgs> {
524 RoutedEvent::register::<InputElement, _>("PointerCaptureLost", RoutingStrategies::DIRECT)
525 }
526 );
527
528 ferro_routed_event!(
529 pub fn pointer_wheel_changed_event() -> RoutedEvent<PointerWheelEventArgs> {
531 RoutedEvent::register::<InputElement, _>(
532 "PointerWheelChanged",
533 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
534 )
535 }
536 );
537
538 ferro_routed_event!(
539 pub fn context_requested_event() -> RoutedEvent<ContextRequestedEventArgs> {
541 RoutedEvent::register::<InputElement, _>(
542 "ContextRequested",
543 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
544 )
545 }
546 );
547
548 ferro_routed_event!(
549 pub fn context_canceled_event() -> RoutedEvent<RoutedEventArgs> {
551 RoutedEvent::register::<InputElement, _>(
552 "ContextCanceled",
553 RoutingStrategies::TUNNEL | RoutingStrategies::BUBBLE,
554 )
555 }
556 );
557
558 fn static_constructor() {
562 Self::context_requested_event();
566 Self::context_canceled_event();
567 Self::register_gesture_events();
568
569 Self::is_enabled_property().changed().subscribe(|e| {
570 if let Some(sender) = e.sender().downcast_ref::<InputElement>() {
571 sender.update_is_effectively_enabled();
572 }
573 });
574
575 Self::got_focus_event().add_class_handler::<InputElement>(|x, e| x.on_got_focus_core(e));
576 Self::lost_focus_event().add_class_handler::<InputElement>(|x, e| x.on_lost_focus_core(e));
577 Self::getting_focus_event().add_class_handler::<InputElement>(|x, e| x.on_getting_focus(e));
578 Self::losing_focus_event().add_class_handler::<InputElement>(|x, e| x.on_losing_focus(e));
579 Self::key_down_event().add_class_handler::<InputElement>(|x, e| x.on_key_down(e));
580 Self::key_up_event().add_class_handler::<InputElement>(|x, e| x.on_key_up(e));
581 Self::text_input_event().add_class_handler::<InputElement>(|x, e| x.on_text_input(e));
582 Self::pointer_entered_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_entered_core(e));
583 Self::pointer_exited_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_exited_core(e));
584 Self::pointer_moved_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_moved(e));
585 Self::pointer_pressed_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_pressed(e));
586 Self::pointer_released_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_released(e));
587 Self::pointer_capture_changing_event()
588 .add_class_handler::<InputElement>(|x, e| x.on_pointer_capture_changing(e));
589 Self::pointer_capture_lost_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_capture_lost(e));
590 Self::pointer_wheel_changed_event().add_class_handler::<InputElement>(|x, e| x.on_pointer_wheel_changed(e));
591 Self::tapped_event().add_class_handler::<InputElement>(|x, e| x.on_tapped(e));
592 Self::right_tapped_event().add_class_handler::<InputElement>(|x, e| x.on_right_tapped(e));
593 Self::double_tapped_event().add_class_handler::<InputElement>(|x, e| x.on_double_tapped(e));
594 Self::holding_event().add_class_handler::<InputElement>(|x, e| x.on_holding(e));
595
596 Gestures::TYPE.ensure_class_init();
597 Gestures::add_tapped(|s, e| {
598 if s.is::<InputElement>() {
599 s.raise_event(e);
600 }
601 });
602 Gestures::add_right_tapped(|s, e| {
603 if s.is::<InputElement>() {
604 s.raise_event(e);
605 }
606 });
607 Gestures::add_double_tapped(|s, e| {
608 if s.is::<InputElement>() {
609 s.raise_event(e);
610 }
611 });
612 Gestures::add_holding(Self::on_preview_holding);
613
614 AccessKeyHandler::access_key_event().add_class_handler::<InputElement>(|x, e| x.on_access_key(e));
616
617 Self::pointer_moved_event().add_class_handler_with::<InputElement>(
619 |x, e| x.on_gesture_pointer_moved(e),
620 Interactive::DEFAULT_ROUTES,
621 true,
622 );
623 Self::pointer_pressed_event().add_class_handler_with::<InputElement>(
624 |x, e| x.on_gesture_pointer_pressed(e),
625 Interactive::DEFAULT_ROUTES,
626 true,
627 );
628 Self::pointer_released_event().add_class_handler_with::<InputElement>(
629 |x, e| x.on_gesture_pointer_released(e),
630 Interactive::DEFAULT_ROUTES,
631 true,
632 );
633 Self::pointer_capture_lost_event().add_class_handler_with::<InputElement>(
634 |x, e| x.on_gesture_pointer_capture_lost(e),
635 Interactive::DEFAULT_ROUTES,
636 true,
637 );
638 }
639
640 pub fn construct() -> Self {
642 Self {
643 base: Interactive::construct(),
644 is_effectively_enabled: Cell::new(true),
645 is_focused: Cell::new(false),
646 is_keyboard_focus_within: Cell::new(false),
647 is_focus_visible: Cell::new(false),
648 is_pointer_over: Cell::new(false),
649 is_context_menu_on_holding: Cell::new(false),
650 key_bindings: OnceCell::new(),
651 gesture_recognizers: OnceCell::new(),
652 }
653 }
654
655 pub fn new() -> Ref<Self> {
656 instantiate(Self::construct())
657 }
658
659 routed_event_accessor!(
662 got_focus, got_focus_event, FocusChangedEventArgs
664 );
665
666 routed_event_accessor!(
667 getting_focus, getting_focus_event, FocusChangingEventArgs
669 );
670
671 routed_event_accessor!(
672 lost_focus, lost_focus_event, FocusChangedEventArgs
674 );
675
676 routed_event_accessor!(
677 losing_focus, losing_focus_event, FocusChangingEventArgs
679 );
680
681 routed_event_accessor!(
682 key_down, key_down_event, KeyEventArgs
684 );
685
686 routed_event_accessor!(
687 key_up, key_up_event, KeyEventArgs
689 );
690
691 routed_event_accessor!(
692 text_input, text_input_event, TextInputEventArgs
694 );
695
696 routed_event_accessor!(
697 text_input_method_client_requested,
700 text_input_method_client_requested_event,
701 TextInputMethodClientRequestedEventArgs
702 );
703
704 routed_event_accessor!(
705 pointer_entered, pointer_entered_event, PointerEventArgs
707 );
708
709 routed_event_accessor!(
710 pointer_exited, pointer_exited_event, PointerEventArgs
712 );
713
714 routed_event_accessor!(
715 pointer_moved, pointer_moved_event, PointerEventArgs
717 );
718
719 routed_event_accessor!(
720 pointer_pressed, pointer_pressed_event, PointerPressedEventArgs
722 );
723
724 routed_event_accessor!(
725 pointer_released, pointer_released_event, PointerReleasedEventArgs
727 );
728
729 routed_event_accessor!(
730 pointer_capture_changing, pointer_capture_changing_event, PointerCaptureChangingEventArgs
733 );
734
735 routed_event_accessor!(
736 pointer_capture_lost, pointer_capture_lost_event, PointerCaptureLostEventArgs
741 );
742
743 routed_event_accessor!(
744 pointer_wheel_changed, pointer_wheel_changed_event, PointerWheelEventArgs
746 );
747
748 routed_event_accessor!(
749 context_requested, context_requested_event, ContextRequestedEventArgs
752 );
753
754 routed_event_accessor!(
755 context_canceled, context_canceled_event, RoutedEventArgs
759 );
760
761 pub fn focusable(&self) -> bool {
765 self.get_value(Self::focusable_property())
766 }
767
768 pub fn set_focusable(&self, value: bool) {
769 self.set_value(Self::focusable_property(), value)
770 }
771
772 pub fn is_enabled(&self) -> bool {
774 self.get_value(Self::is_enabled_property())
775 }
776
777 pub fn set_is_enabled(&self, value: bool) {
778 self.set_value(Self::is_enabled_property(), value)
779 }
780
781 pub fn cursor(&self) -> Option<Rc<Cursor>> {
783 self.get_value(Self::cursor_property())
784 }
785
786 pub fn set_cursor(&self, value: Option<Rc<Cursor>>) {
787 self.set_value(Self::cursor_property(), value)
788 }
789
790 #[inline]
793 pub fn is_keyboard_focus_within(&self) -> bool {
794 self.is_keyboard_focus_within.get()
795 }
796
797 pub(crate) fn set_is_keyboard_focus_within(&self, value: bool) {
798 self.set_and_raise_cell(Self::is_keyboard_focus_within_property(), &self.is_keyboard_focus_within, value);
799 }
800
801 #[inline]
803 pub fn is_focused(&self) -> bool {
804 self.is_focused.get()
805 }
806
807 fn set_is_focused(&self, value: bool) {
808 self.set_and_raise_cell(Self::is_focused_property(), &self.is_focused, value);
809 }
810
811 pub fn is_hit_test_visible(&self) -> bool {
813 self.get_value(Self::is_hit_test_visible_property())
814 }
815
816 pub fn set_is_hit_test_visible(&self, value: bool) {
817 self.set_value(Self::is_hit_test_visible_property(), value)
818 }
819
820 #[inline]
822 pub fn is_pointer_over(&self) -> bool {
823 self.is_pointer_over.get()
824 }
825
826 pub(crate) fn set_is_pointer_over(&self, value: bool) {
827 self.set_and_raise_cell(Self::is_pointer_over_property(), &self.is_pointer_over, value);
828 }
829
830 pub fn is_tab_stop(&self) -> bool {
832 self.get_value(Self::is_tab_stop_property())
833 }
834
835 pub fn set_is_tab_stop(&self, value: bool) {
836 self.set_value(Self::is_tab_stop_property(), value)
837 }
838
839 #[inline]
841 pub fn is_effectively_enabled(&self) -> bool {
842 self.is_effectively_enabled.get()
843 }
844
845 fn set_is_effectively_enabled(&self, value: bool) {
846 self.set_and_raise_cell(Self::is_effectively_enabled_property(), &self.is_effectively_enabled, value);
847 self.pseudo_classes().set(":disabled", !value);
848
849 if !self.is_effectively_enabled() {
850 if let Some(focus_manager) = FocusManager::get_focus_manager(self) {
851 let is_focused_element = focus_manager
852 .get_focused_element()
853 .is_some_and(|focused| std::ptr::eq::<InputElement>(&*focused, self));
854
855 if is_focused_element {
856 focus_manager.focus(None, NavigationMethod::Unspecified, KeyModifiers::NONE);
857 }
858 }
859 }
860 }
861
862 pub fn tab_index(&self) -> i32 {
865 self.get_value(Self::tab_index_property())
866 }
867
868 pub fn set_tab_index(&self, value: i32) {
869 self.set_value(Self::tab_index_property(), value)
870 }
871
872 pub fn key_bindings(&self) -> FerroList<Ref<KeyBinding>> {
876 self.key_bindings.get_or_init(FerroList::new).clone()
877 }
878
879 pub fn gesture_recognizers(&self) -> GestureRecognizerCollection {
881 self.gesture_recognizers.get_or_init(|| GestureRecognizerCollection::new(&self.to_ref())).clone()
882 }
883
884 fn on_gesture_pointer_released(&self, e: &PointerReleasedEventArgs) {
885 if !e.is_gesture_recognition_skipped() {
886 if let Some(recognizers) = self.gesture_recognizers.get() {
887 if recognizers.handle_pointer_released(e) {
888 e.set_handled(true);
889 }
890 }
891 }
892 }
893
894 fn on_gesture_pointer_capture_lost(&self, e: &PointerCaptureLostEventArgs) {
895 if let Some(recognizers) = self.gesture_recognizers.get() {
896 recognizers.handle_capture_lost(e.pointer());
897 }
898 }
899
900 fn on_gesture_pointer_pressed(&self, e: &PointerPressedEventArgs) {
901 if !e.is_gesture_recognition_skipped() {
902 if let Some(recognizers) = self.gesture_recognizers.get() {
903 if recognizers.handle_pointer_pressed(e) {
904 e.set_handled(true);
905 }
906 }
907 }
908 }
909
910 fn on_gesture_pointer_moved(&self, e: &PointerEventArgs) {
911 if !e.is_gesture_recognition_skipped() {
912 if let Some(recognizers) = self.gesture_recognizers.get() {
913 if recognizers.handle_pointer_moved(e) {
914 e.set_handled(true);
915 }
916 }
917 }
918 }
919
920 pub fn focus(&self) -> bool {
925 self.focus_with(NavigationMethod::Unspecified, KeyModifiers::NONE)
926 }
927
928 pub fn focus_with(&self, method: NavigationMethod, key_modifiers: KeyModifiers) -> bool {
934 match FocusManager::get_focus_manager(self) {
935 Some(focus_manager) => focus_manager.focus(Some(&self.to_ref()), method, key_modifiers),
936 None => false,
937 }
938 }
939
940 pub(crate) fn process_tab_stop(
944 _content_root: Option<&Ref<InputElement>>,
945 focused_element: Option<&Ref<InputElement>>,
946 candidate_tab_stop_element: Option<&Ref<InputElement>>,
947 is_reverse: bool,
948 did_cycle_focus_at_root_visual: bool,
949 ) -> (bool, Option<Ref<InputElement>>) {
950 let new_tab_stop: Option<Ref<InputElement>> = None;
953 let mut is_tab_stop_overridden = false;
954 let mut sp_new_tab_stop: Option<Ref<InputElement>> = None;
955
956 if let Some(focused) = focused_element {
957 let (overridden, tab_stop) = focused.process_tab_stop_internal(
958 candidate_tab_stop_element,
959 is_reverse,
960 did_cycle_focus_at_root_visual,
961 );
962 is_tab_stop_overridden = overridden;
963 sp_new_tab_stop = tab_stop;
964 }
965
966 if !is_tab_stop_overridden {
967 if let Some(candidate) = candidate_tab_stop_element {
968 let (overridden, tab_stop) =
969 candidate.process_candidate_tab_stop_internal(focused_element, None, is_reverse);
970 is_tab_stop_overridden = overridden;
971 sp_new_tab_stop = tab_stop;
972 }
973 }
974
975 let _ = sp_new_tab_stop;
979
980 (is_tab_stop_overridden, new_tab_stop)
981 }
982
983 fn process_tab_stop_internal(
984 &self,
985 candidate_tab_stop_element: Option<&Ref<InputElement>>,
986 is_reverse: bool,
987 did_cycle_focus_at_root_visual: bool,
988 ) -> (bool, Option<Ref<InputElement>>) {
989 let this = self.to_ref();
990 let mut current = Some(this.clone());
991 let mut new_tab_stop = None;
992 let mut candidate_tab_stop_overridden = false;
993
994 while let Some(c) = current {
995 if candidate_tab_stop_overridden {
996 break;
997 }
998
999 candidate_tab_stop_overridden = c.process_tab_stop_override(
1000 Some(&this),
1001 candidate_tab_stop_element,
1002 is_reverse,
1003 did_cycle_focus_at_root_visual,
1004 &mut new_tab_stop,
1005 );
1006 current = c.parent().and_then(|parent| parent.downcast::<InputElement>().ok());
1007 }
1008
1009 (candidate_tab_stop_overridden, new_tab_stop)
1010 }
1011
1012 fn process_candidate_tab_stop_internal(
1013 &self,
1014 current_tab_stop: Option<&Ref<InputElement>>,
1015 overriden_candidate_tab_stop_element: Option<&Ref<InputElement>>,
1016 is_reverse: bool,
1017 ) -> (bool, Option<Ref<InputElement>>) {
1018 let this = self.to_ref();
1019 let mut current = Some(this.clone());
1020 let mut new_tab_stop = None;
1021 let mut candidate_tab_stop_overridden = false;
1022
1023 while let Some(c) = current {
1024 if candidate_tab_stop_overridden {
1025 break;
1026 }
1027
1028 candidate_tab_stop_overridden = c.process_candidate_tab_stop_override(
1029 current_tab_stop,
1030 Some(&this),
1031 overriden_candidate_tab_stop_element,
1032 is_reverse,
1033 &mut new_tab_stop,
1034 );
1035 current = c.parent().and_then(|parent| parent.downcast::<InputElement>().ok());
1036 }
1037
1038 (candidate_tab_stop_overridden, new_tab_stop)
1039 }
1040
1041 fn on_got_focus_core(&self, e: &FocusChangedEventArgs) {
1042 let is_focused = e.is_source(self);
1043 self.is_focus_visible.set(
1044 is_focused
1045 && (e.navigation_method == NavigationMethod::Directional
1046 || e.navigation_method == NavigationMethod::Tab),
1047 );
1048 self.set_is_focused(is_focused);
1049 self.on_got_focus(e);
1050 }
1051
1052 fn on_lost_focus_core(&self, e: &FocusChangedEventArgs) {
1053 self.is_focus_visible.set(false);
1054 self.set_is_focused(false);
1055 self.on_lost_focus(e);
1056 }
1057
1058 pub fn update_is_effectively_enabled(&self) {
1061 let parent = self.get_visual_parent_of_type::<InputElement>();
1062 self.update_is_effectively_enabled_from(parent.as_deref());
1063 }
1064
1065 fn on_pointer_entered_core(&self, e: &PointerEventArgs) {
1066 self.set_is_pointer_over(true);
1067 self.on_pointer_entered(e);
1068 }
1069
1070 fn on_pointer_exited_core(&self, e: &PointerEventArgs) {
1071 self.set_is_pointer_over(false);
1072 self.on_pointer_exited(e);
1073 }
1074
1075 fn update_is_effectively_enabled_from(&self, parent: Option<&InputElement>) {
1078 self.set_is_effectively_enabled(
1079 self.is_enabled_core() && parent.is_none_or(InputElement::is_effectively_enabled),
1080 );
1081
1082 if let Some(children) = self.visual_children_snapshot() {
1084 for child in children.iter() {
1085 if let Some(child) = child.downcast_ref::<InputElement>() {
1086 child.update_is_effectively_enabled_from(Some(self));
1087 }
1088 }
1089 }
1090 }
1091
1092 fn update_pseudo_classes(&self, is_focused: Option<bool>, is_pointer_over: Option<bool>) {
1093 if let Some(is_focused) = is_focused {
1094 self.pseudo_classes().set(":focus", is_focused);
1095 self.pseudo_classes().set(":focus-visible", self.is_focus_visible.get());
1096 }
1097
1098 if let Some(is_pointer_over) = is_pointer_over {
1099 self.pseudo_classes().set(":pointerover", is_pointer_over);
1100 }
1101 }
1102}
1103
1104impl IInputElement for InputElement {
1105 fn focusable(&self) -> bool {
1106 InputElement::focusable(self)
1107 }
1108
1109 fn is_enabled(&self) -> bool {
1110 InputElement::is_enabled(self)
1111 }
1112
1113 fn cursor(&self) -> Option<Rc<Cursor>> {
1114 InputElement::cursor(self)
1115 }
1116
1117 fn is_effectively_enabled(&self) -> bool {
1118 InputElement::is_effectively_enabled(self)
1119 }
1120
1121 fn is_effectively_visible(&self) -> bool {
1122 Visual::is_effectively_visible(self)
1123 }
1124
1125 fn is_keyboard_focus_within(&self) -> bool {
1126 InputElement::is_keyboard_focus_within(self)
1127 }
1128
1129 fn is_focused(&self) -> bool {
1130 InputElement::is_focused(self)
1131 }
1132
1133 fn is_hit_test_visible(&self) -> bool {
1134 InputElement::is_hit_test_visible(self)
1135 }
1136
1137 fn is_pointer_over(&self) -> bool {
1138 InputElement::is_pointer_over(self)
1139 }
1140
1141 fn focus(&self, method: NavigationMethod, key_modifiers: KeyModifiers) -> bool {
1142 InputElement::focus_with(self, method, key_modifiers)
1143 }
1144}